導航:首頁 > 源碼編譯 > 軟體序列號一般用什麼演算法

軟體序列號一般用什麼演算法

發布時間:2023-09-06 08:31:23

『壹』 序列號保護加密的原理和驗證方法

(1)序列號保護機制

數學演算法一項都是密碼加密的核心,但在一般的軟體加密中,它似乎並不太為人們關心,因為大多數時候軟體加密本身實現的都是一種編程的技巧。但近幾年來隨著序列號加密程序的普及,數學演算法在軟體加密中的比重似乎是越來越大了。
我們先來看看在網路上大行其道的序列號加密的工作原理。當用戶從網路上下載某個shareware——共享軟體後,一般都有使用時間上的限制,當過了共享軟體的試用期後,你必須到這個軟體的公司去注冊後方能繼續使用。注冊過程一般是用戶把自己的私人信息(一般主要指名字)連同信用卡號碼告訴給軟體公司,軟體公司會根據用戶的信息計算出一個序列碼,在用戶得到這個序列碼後,按照注冊需要的步驟在軟體中輸入注冊信息和注冊碼,其注冊信息的合法性由軟體驗證通過後,軟體就會取消掉本身的各種限制,這種加密實現起來比較簡單,不需要額外的成本,用戶購買也非常方便,在互聯網上的軟體80%都是以這種方式來保護的。
我們注意到軟體驗證序列號的合法性過程,其實就是驗證用戶名和序列號之間的換算關系是否正確的過程。其驗證最基本的有兩種,一種是按用戶輸入的姓名來生成注冊碼,再同用戶輸入的注冊碼比較,公式表示如下:
序列號 = F(用戶名)
但這種方法等於在用戶軟體中再現了軟體公司生成注冊碼的過程,實際上是非常不安全的,不論其換算過程多麼復雜,解密者只需把你的換算過程從程序中提取出來就可以編制一個通用的注冊程序。

另外一種是通過注冊碼來驗證用戶名的正確性,公式表示如下:
用戶名稱 = F逆(序列號) (如ACDSEE,小樓注)
這其實是軟體公司注冊碼計算過程的反演算法,如果正向演算法與反向演算法不是對稱演算法的話,對於解密者來說,的確有些困難,但這種演算法相當不好設計。

於是有人考慮到一下的演算法:
F1(用戶名稱) = F2(序列號)
F1、F2是兩種完全不同的的演算法,但用戶名通過F1演算法的計算出的特徵字等於序列號通過F2演算法計算出的特徵字,這種演算法在設計上比較簡單,保密性相對以上兩種演算法也要好的多。如果能夠把F1、F2演算法設計成不可逆演算法的話,保密性相當的好;可一旦解密者找到其中之一的反演算法的話,這種演算法就不安全了。一元演算法的設計看來再如何努力也很難有太大的突破,那麼二元呢?

特定值 = F(用戶名,序列號)
這個演算法看上去相當不錯,用戶名稱與序列號之間的關系不再那麼清晰了,但同時也失去了用戶名於序列號的一一對應關系,軟體開發者必須自己維護用戶名稱與序列號之間的唯一性,但這似乎不是難以辦到的事,建個資料庫就好了。當然你也可以根據這一思路把用戶名稱和序列號分為幾個部分來構造多元的演算法。
特定值 = F(用戶名1,用戶名2,...序列號1,序列號2...)

現有的序列號加密演算法大多是軟體開發者自行設計的,大部分相當簡單。而且有些演算法作者雖然下了很大的功夫,效果卻往往得不到它所希望的結果。其實現在有很多現成的加密演算法可以用,如RSADES,MD4,MD5,只不過這些演算法是為了加密密文或密碼用的,於序列號加密多少有些不同。我在這里試舉一例,希望有拋磚引玉的作用:
1、在軟體程序中有一段加密過的密文S
2、密鑰 = F(用戶名、序列號) 用上面的二元演算法得到密鑰
3、明文D = F-DES(密文S、密鑰) 用得到的密鑰來解密密文得到明文D
4、CRC = F-CRC(明文D) 對得到的明文應用各種CRC統計
5、檢查CRC是否正確。最好多設計幾種CRC演算法,檢查多個CRC結果是否都正確
用這種方法,在沒有一個已知正確的序列號情況下是永遠推算不出正確的序列號的。

(2)如何攻擊序列號保護

要找到序列號,或者修改掉判斷序列號之後的跳轉指令,最重要的是要利用各種工具定位判斷序列號的代碼段。這些常用的API包括GetDlgItemInt, GetDlgItemTextA, GetTabbedTextExtentA, GetWindowTextA, Hmemcpy (僅僅Windows 9x), lstrcmp, lstrlen, memcpy (限於NT/2000)。

1)數據約束性的秘訣
這個概念是+ORC提出的,只限於用明文比較注冊碼的那種保護方式。在大多數序列號保護的程序中,那個真正的、正確的注冊碼或密碼(Password)會於某個時刻出現在內存中,當然它出現的位置是不定的,但多數情況下它會在一個范圍之內,即存放用戶輸入序列號的內存地址±0X90位元組的地方。這是由於加密者所用工具內部的一個Windows數據傳輸的約束條件決定的。

2)Hmemcpy函數(俗稱萬能斷點)
函數Hmemcpy是Windows9x系統的內部函數,位於KERNEL32.DLL中,它的作用是將內存中的一塊數據拷貝到另一個地方。由於Windows9x系統頻繁使用該函數處理各種字串,因此用它作為斷點很實用,它是Windows9x平台最常用的斷點。在Windows NT/2K中沒有這個斷點,因為其內核和Windows9x完全不同。

3)S命令
由於S命令忽略不在內存中的頁面,因此你可以使用32位平面地址數據段描述符30h在整個4GB(0~FFFFFFFFh )空間查找,一般用在Windows9x下面。具體步驟為:先輸入姓名或假的序列號(如: 78787878),按Ctrl+D切換到SoftICE下,下搜索命令:
s 30:0 L ffffffff '78787878'
會搜索出地址:ss:ssssssss(這些地址可能不止一個),然後用bpm斷點監視搜索到的假注冊碼,跟蹤一下程序如何處理輸入的序列號,就有可能找到正確的序列號。

4)利用消息斷點
在處理字串方面可以利用消息斷點WM_GETTEXT和WM_COMMAND。前者用來讀取某個控制項中的文本,比如拷貝編輯窗口中的序列號到程序提供的一個緩沖區里;後者則是用來通知某個控制項的父窗口的,比如當輸入序列號之後點擊OK按鈕,則該按鈕的父窗口將收到一個WM_COMMAND消息,以表明該按鈕被點擊。
BMSG xxxx WM_GETTEXT (攔截序列號)
BMSG xxxx WM_COMMAND (攔截OK按鈕)
可以用SoftICE提供的HWND命令獲得窗口句柄的信息,也可以利用Visual Studio中的Spy++實用工具得到相應窗口的句柄值,然後用BMSG設斷點攔截。例:
BMSG 0129 WM_COMMAND

『貳』 求序列號生成演算法

隨機序列的演算法
作者:unknown 更新時間:2005-03-17

找到了兩個演算法, 第一個很簡單, 但可惜不是隨機的, 第二個是典型的偽隨機數演算法, 可惜要用到2的幾百萬次方這樣巨大的整數, 真痛苦
要是有UNIX上計算密碼的源代碼就好了

第一種做法:
f(k) = (k*F(N-1)) mod F(N)
其中,
k是一個序列號, 就是要取的那個數的順序號
F(N)是這樣一個序列 F(0) = 0, F(1) = 1, F(N+2) = F(N+1)+F(N) (for N>=0)

第二種做法

V = ( ( V * 2 ) + B .xor. B ... )(Mod 2^n)
N+1 N 0 2
V是要取的隨機數, B是個種子, n是隨機數的最大個數

原來這個問題, 很高難, 不少數學高手都為解決這個問題寫了論文, 咳咳, 偶真是個白痴

呵呵, 效果肯定是不錯啦, 因為用不到很大的表.
至於應用是這樣的, 比如, 你要給每個用戶在注冊的時候一個ID但有不希望用戶在看到自己的ID的時候能知道其他用戶的ID, 如果用SEQUENCE來生成ID的話, 一個用戶只要把自己的ID減1就能得到其它用戶的ID了. 所以要用隨機數來做ID, 這樣用戶很難猜到其他用戶的ID了.

當然主要的問題是, 隨機數可能重復. 因此希望使用一個隨機數做種子用它來確定一組"無規律"的自然數序列, 並且在這個序列中不會出現重復的自然數. 在這里使用的方法生成的序列並不是沒有規律的, 只不過這個軌律很難被發現就是了.
Xn+1 = (aXn + b) mod c (其中, abc通常是質數)是一種被廣泛使用的最簡單的隨機數發生演算法, 有研究表表明這個演算法生成的隨機數基本上符合統計規律, JAVA, BORLAND C等用的都是這個方法, 一般只要保證第一個種子是真正的隨機數就行了,

下面來說一下重復的問題,
上述方法會有可能出現重復, 因為當(aXn + b)有可能是同樣的數或者說余數相同的數, 因此要想不重復就得變形
偶想到的方法是
Xn=(a*n + b) mod c n是一個在1到c之間的整數, a*n + b就是一個線性公式了, 且若n不同則a*n + b也不同, 它們除上質數c得到的余數也肯定不同, 因為 若不考慮a和b而只有n的時候, 每次的結果都是n,而線性公式, 只不過移動了這條直線的位置和斜率而已, 每個結果仍然不會相同的,
為了增加不可預計性, 偶又為上面那個公式設計了, 隨機數種子, 於是就變成了這個樣子
F(N)=(隨機數*(N+隨機數))MOD 一個質數
這樣就能夠產生 1到選定質數之間的一個"無規律"的自然數序列了, 只要改變隨機數就能改變序列的次序

在應用的時候, 要把隨機數種子和最後用到的序列號保存到一個表裡, 每此使用的時候取出來算好, 再把序列號更新一下就可以了
具體地說, 就是可以建一個表來保存每個序列的隨機數種子, 然後再為這個序列建一個SEQUENCE就行了
然後就
SELECT MOD(序列控製表.隨機數*(SEQ.NEXTVAL+序列控製表.隨機數)),序列控製表.質數)
FROM 序列控製表
WHERE 序列控製表.序列ID=XX
就OK了
注意 序列控製表.質數 決定了序列的范圍

http://www.ddvip.net/database/mssql/index2/81.htm /* CopyRight */

當然,我以前也見過那種類型的,就是「真隨機」,大概是根據隨機按鍵的鍵位和滑鼠在CRT上任意的「隨機」位置以及當時的系統時間(或相對間隔,一般至少毫秒級)來適應某種較復雜的演算法來產生的。...其實,可以產生隨機效應的自變數的確是很多的,就看你怎麼用好了。

去看看系統論和混沌學吧,還有高等數學中的分形理論和物理熱學中的耗散結構理論,可能會有所幫助,呵呵。
最後,倒有興趣問問你要的隨機數是做什麼用呢,是個子問題嗎?

『叄』 軟體編程經常用的演算法都有哪些

排序演算法 所謂排序,就是使一串記錄,按照其中的某個或某些關鍵字的大小,遞增或遞減的排列起來的操作。
分類
在計算機科學所使用的排序演算法通常被分類為:
計算的復雜度(最差、平均、和最好表現),依據串列(list)的大小(n)。一般而言,好的表現是O。(n log n),且壞的行為是Ω(n2)。對於一個排序理想的表現是O(n)。僅使用一個抽象關鍵比較運算的排序演算法總平均上總是至少需要Ω(n log n)。
記憶體使用量(以及其他電腦資源的使用)
穩定度:穩定排序演算法會依照相等的關鍵(換言之就是值)維持紀錄的相對次序。也就是一個排序演算法是穩定的,就是當有兩個有相等關鍵的紀錄R和S,且在原本的串列中R出現在S之前,在排序過的串列中R也將會是在S之前。
一般的方法:插入、交換、選擇、合並等等。交換排序包含冒泡排序(bubble sort)和快速排序(quicksort)。選擇排序包含shaker排序和堆排序(heapsort)。
當相等的元素是無法分辨的,比如像是整數,穩定度並不是一個問題。然而,假設以下的數對將要以他們的第一個數字來排序。
(4, 1) (3, 1) (3, 7) (5, 6)
在這個狀況下,有可能產生兩種不同的結果,一個是依照相等的鍵值維持相對的次序,而另外一個則沒有:
(3, 1) (3, 7) (4, 1) (5, 6) (維持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改變)
不穩定排序演算法可能會在相等的鍵值中改變紀錄的相對次序,但是穩定排序演算法從來不會如此。不穩定排序演算法可以被特別地時作為穩定。作這件事情的一個方式是人工擴充鍵值的比較,如此在其他方面相同鍵值的兩個物件間之比較,就會被決定使用在原先資料次序中的條目,當作一個同分決賽。然而,要記住這種次序通常牽涉到額外的空間負擔。
排列演算法列表
在這個表格中,n是要被排序的紀錄數量以及k是不同鍵值的數量。
穩定的
冒泡排序(bubble sort) — O(n2)
雞尾酒排序 (Cocktail sort, 雙向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 額外 記憶體
計數排序 (counting sort) — O(n+k); 需要 O(n+k) 額外 記憶體
歸並排序 (merge sort)— O(n log n); 需要 O(n) 額外記憶體
原地歸並排序 — O(n2)
二叉樹排序 (Binary tree sort) — O(n log n); 需要 O(n) 額外記憶體
鴿巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 額外記憶體
基數排序 (radix sort)— O(n·k); 需要 O(n) 額外記憶體
Gnome sort — O(n2)
Library sort — O(n log n) with high probability, 需要 (1+ε)n 額外記憶體
不穩定
選擇排序 (selection sort)— O(n2)
希爾排序 (shell sort)— O(n log n) 如果使用最佳的現在版本
Comb sort — O(n log n)
堆排序 (heapsort)— O(n log n)
Smoothsort — O(n log n)
快速排序 (quicksort)— O(n log n) 期望時間, O(n2) 最壞情況; 對於大的、亂數串列一般相信是最快的已知排序
Introsort — O(n log n)
Patience sorting — O(n log n + k) 最外情況時間, 需要 額外的 O(n + k) 空間, 也需要找到最長的遞增子序列(longest increasing subsequence)
不實用的排序演算法
Bogo排序 — O(n × n!) 期望時間, 無窮的最壞情況。
Stupid sort — O(n3); 遞回版本需要 O(n2) 額外記憶體
Bead sort — O(n) or O(√n), 但需要特別的硬體
Pancake sorting — O(n), 但需要特別的硬體
排序的演算法
排序的演算法有很多,對空間的要求及其時間效率也不盡相同。下面列出了一些常見的排序演算法。這裡面插入排序和冒泡排序又被稱作簡單排序,他們對空間的要求不高,但是時間效率卻不穩定;而後面三種排序相對於簡單排序對空間的要求稍高一點,但時間效率卻能穩定在很高的水平。基數排序是針對關鍵字在一個較小范圍內的排序演算法。
插入排序
冒泡排序
選擇排序
快速排序
堆排序
歸並排序
基數排序
希爾排序
插入排序
插入排序是這樣實現的:
首先新建一個空列表,用於保存已排序的有序數列(我們稱之為"有序列表")。
從原數列中取出一個數,將其插入"有序列表"中,使其仍舊保持有序狀態。
重復2號步驟,直至原數列為空。
插入排序的平均時間復雜度為平方級的,效率不高,但是容易實現。它藉助了"逐步擴大成果"的思想,使有序列表的長度逐漸增加,直至其長度等於原列表的長度。
冒泡排序
冒泡排序是這樣實現的:
首先將所有待排序的數字放入工作列表中。
從列表的第一個數字到倒數第二個數字,逐個檢查:若某一位上的數字大於他的下一位,則將它與它的下一位交換。
重復2號步驟,直至再也不能交換。
冒泡排序的平均時間復雜度與插入排序相同,也是平方級的,但也是非常容易實現的演算法。
選擇排序
選擇排序是這樣實現的:
設數組內存放了n個待排數字,數組下標從1開始,到n結束。
i=1
從數組的第i個元素開始到第n個元素,尋找最小的元素。
將上一步找到的最小元素和第i位元素交換。
如果i=n-1演算法結束,否則回到第3步
選擇排序的平均時間復雜度也是O(n²)的。
快速排序
現在開始,我們要接觸高效排序演算法了。實踐證明,快速排序是所有排序演算法中最高效的一種。它採用了分治的思想:先保證列表的前半部分都小於後半部分,然後分別對前半部分和後半部分排序,這樣整個列表就有序了。這是一種先進的思想,也是它高效的原因。因為在排序演算法中,演算法的高效與否與列表中數字間的比較次數有直接的關系,而"保證列表的前半部分都小於後半部分"就使得前半部分的任何一個數從此以後都不再跟後半部分的數進行比較了,大大減少了數字間不必要的比較。但查找數據得另當別論了。
堆排序
堆排序與前面的演算法都不同,它是這樣的:
首先新建一個空列表,作用與插入排序中的"有序列表"相同。
找到數列中最大的數字,將其加在"有序列表"的末尾,並將其從原數列中刪除。
重復2號步驟,直至原數列為空。
堆排序的平均時間復雜度為nlogn,效率高(因為有堆這種數據結構以及它奇妙的特徵,使得"找到數列中最大的數字"這樣的操作只需要O(1)的時間復雜度,維護需要logn的時間復雜度),但是實現相對復雜(可以說是這里7種演算法中比較難實現的)。
看起來似乎堆排序與插入排序有些相像,但他們其實是本質不同的演算法。至少,他們的時間復雜度差了一個數量級,一個是平方級的,一個是對數級的。
平均時間復雜度
插入排序 O(n2)
冒泡排序 O(n2)
選擇排序 O(n2)
快速排序 O(n log n)
堆排序 O(n log n)
歸並排序 O(n log n)
基數排序 O(n)
希爾排序 O(n1.25)
冒泡排序
654
比如說這個,我想讓它從小到大排序,怎麼做呢?
第一步:6跟5比,發現比它大,則交換。564
第二步:5跟4比,發現比它大,則交換。465
第三步:6跟5比,發現比它大,則交換。456

閱讀全文

與軟體序列號一般用什麼演算法相關的資料

熱點內容
卡耐基pdf下載 瀏覽:922
現在最流行的單片機 瀏覽:88
機頂盒刷機源碼 瀏覽:985
編碼pdf下載 瀏覽:944
隔壁同學app怎麼 瀏覽:299
c語言宏命令 瀏覽:542
php卡死源碼 瀏覽:574
time庫中的clock函數python 瀏覽:989
cad視覺移動命令怎麼打開 瀏覽:821
安卓java調用python 瀏覽:395
java標准時間 瀏覽:137
華為伺服器湖北渠道商雲主機 瀏覽:30
韓式面部護理解壓視頻 瀏覽:301
pdf換成jpg圖片 瀏覽:897
dh加密演算法 瀏覽:107
安卓手機如何隱藏微信信息提示 瀏覽:632
nodejs解壓縮 瀏覽:262
直流雙轉子壓縮機 瀏覽:952
pythonxmlstring 瀏覽:822
用私鑰加密之後可以用公鑰解密 瀏覽:788