1 前言
目前,商用軟件和共享軟件絕大部份都是采用注冊碼授權的方式來保證軟件本身不被盜用,以保證自身的利益。盡管很多常用的許多軟件系統的某些版本已經被別人破解,但對於軟件特殊行業而言,注冊碼授權的方式還是一種保護軟件系統本身的一種有效的手段。
通常而言,注冊碼授權方式有以下幾種方式:
u 安裝序列號方式:這是最為常用的方式,Mircosoft提供的產品(例如:Windows系列產品、Office系列產品等等)都是采用這種方式。通過一種復雜的算法生成安裝序列號,在安裝過程中,安裝程序對用戶輸入的安裝序列號進行校驗來驗證該系統是否被合法,從而完成授權。
u 用戶名+序列號方式:即軟件系統的供應商給用戶提供有效的用戶名和序列號,用戶在安裝過程或啟動過程中輸入有效的用戶名和序列號,系統通過算法校驗通過后完成軟件授權。
u 在線注冊方式:用戶安裝系統后,通過網絡進行注冊授權。軟件系統的供應商事先已經登記了用戶的信息,用戶在線注冊時,供應商的注冊系統對用戶的信息進行驗證。用戶身份有效時,注冊系統生成一個憑證信息,軟件系統根據憑證信息完成授權。
和 "基於RSA算法實現軟件注冊碼原理初討" 有關的 c#、asp.net、c++ 編程小帖士: strong>Insert()在字串中指定索引位插入指定字符。如: str1.Insert(1,"字");在str1的第二個字符處插入“字”,如果str1="中國",插入后為“中字國”; |
u 激活碼方式:用戶安裝系統后,軟件系統會根據用戶機器的關鍵信息(例如:MAC地址、CPU序列號、硬盤序列號等等)生成一個注冊憑證(也可稱為注冊碼),用戶將這個注冊憑證發送給軟件供應商,供應商通過注冊憑證生成一個激活碼。用戶輸入激活碼,軟件系統完成授權。
不論是采用哪種方式來進行授權,理論上都是可以被破解的。只要破解者發現了軟件授權機制和原理則任何保護機制都將化為烏有。因此,只能夠通過選擇復雜的算法和機制來增加破解者的破解難度,從而在在一定的時間內保證軟件不被盜用。
RSA算法(非對稱加密算法)是一個廣泛用於加密和數字簽名的算法,可以適用用戶名+序列號、在線注冊、激活碼等軟件保護方式
2 RSA算法介紹
RSA算法是第一個能同時用於加密和數字簽名的算法,也易於理解和操作。 RSA也是被研究得最廣泛的公鑰算法,從提出到現在已近二十年,經歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。
RSA的安全性依賴於大數的因子分解,但並沒有從理論上證明破譯RSA的難度與大數分解難度等價,即RSA的重大缺陷是無法從理論上把握它的保密性能如何,而且密碼學界多數人士傾向於因子分解不是NPC問題。
RSA的缺點主要有:
(一) 產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。
(二) 分組長度太大,為保證安全性,n 至少也要 600 bits以上,使運算代價很高,尤其是速度較慢,較對稱密碼算法慢幾個數量級;且隨着大數分解技術的發展,這個長度還在增加,不利於數據格式的標准化。
但RSA的缺點對軟件注冊碼而言都不是問題,因為軟件注冊機可以選擇一個已知的素數來生成公鑰和私鑰。至於運算代價很高的問題而言也不是問題,因為注冊憑證信息量是很小的。
RSA理論的數學基礎是數論中的歐拉定理,基本原理如下:
(一) 取兩個相近的大素數p、q;
(二) 計算n=p*q,z=(p-1)*(q-1);
(三) 任取一個與z互素的整數e;
(四) 計算滿足e*d=1 mod z 的整數d;
(五) 將明文m分成字符塊s加密,每個塊s小於n。
(六) 加密:c=m^e mod n;解密:m=c^d mod n
(七) (n,e)和(n,d)分別稱為“公開密鑰”和“秘密密鑰”。根據Euler定理可得:m=c^d mod n=(m^e mod n)^d mod n=m;
舉例說明:
(一) 取兩個素數p=11和q=13
(二) 計算n=p*q=11*13=143,z=(p-1)*(q-1)=(11-1)*(13-1)=120;
(三) 選取與z=120互素的整數e,如e=7,現可計算出滿足7*d=1 mod 120的整數d=103,即:7*103=1 mod 120、7*103/120余1,
(四) 整理如下:p=11、q=13、n=143、e=7、d=103
(五) 得出公鑰 (n,e)=(143,7)和私鑰 (n,d)=(143,103)
以數據加密為例:
(一) 甲向乙發送機密數據信息m=85,並已知乙的公鑰(n,e)=(143,7),於是可計算得出:c=m^e mod n=85^7 mod 143=123,甲將c發送至乙;
(二) 乙利用私鑰(n,d)=(143,103)對c進行計算:m=c^d mod n=123^103 mod 143=85,現乙已經得到甲向其要發送的機密數據信息,而甲向乙發送信息時,甲所擁有的僅僅是乙的公鑰;
由此可知,由(n,e)加密的數據只能用(n,d)解密,反之亦然,從而證明RSA加密算法是可逆的,但RSA的可逆是基於特定的數值對(即稱為公鑰和私鑰)。
另外,RSA算法的安全性依賴於大數分解,公鑰和私鑰都是兩個大素數(大於100個十進制位)的函數。從理論上講,從一個密鑰和密文推斷出明文的難度等同於分解兩個大素數的積,因此,只要選擇足夠大的素數、保證公鑰或私鑰的安全,則采用常規的破解難度是非常大的,基本上可以認定為不可能破解,由此可以認定RSA是安全的。
3 采用RSA算法實現注冊碼的基本原理
本文檔只描述用戶名+序列號、在線注冊、激活碼三種方式,其它方式不予考慮。
下面分別描述三種方式實現的基本原理:
3.1 用戶名+序列號
1. 生成一對公鑰E和私鑰D(供軟件注冊模板和注冊機使用);
2. 軟件供應商編寫一個注冊機,通過注冊機將輸入的用戶名與私鑰D加密碼生成密碼C(即:注冊碼);軟件供應商將用戶名及注冊碼提供給用戶。
3. 用戶安裝軟件后,輸入用戶名和注冊碼,軟件注冊模板采用公鑰E對注冊碼解碼后生成F(即:用戶名);
4. 軟件注冊模板比較解碼后的用戶名F與輸入的用戶名,如果相等則用戶合法,完成授權,否則授權失敗。
3.2 在線注冊
1. 生成一對公鑰E和私鑰D(供注冊系統和注冊模板使用);
2. 軟件供應商將用戶的憑證信息通過私鑰D加密后生成F,並存儲在特定的地方,比如說:存儲在注冊數據庫中;
3. 用戶安裝軟件后,輸入用戶特征信息后,軟件注冊模板采用公鑰E對用戶特征信息加密,形式成注冊憑證C,通過網絡發送到供應商的注冊系統中。
4. 注冊系統采用私鑰D加密用戶注冊憑證C,生成F。通過F判斷用戶身份的有效性;
5. 注冊系統將注冊驗證的結果通過私鑰D加密后,通過網絡發送給軟件系統;
6. 軟件注冊模板采用公鑰E對驗證結果進行解密,根據結果來決定是否完成授權;
3.3 激活碼
1. 生成一對公鑰E和私鑰D(供軟件注冊模板和注冊機使用);
2. 用戶安裝軟件后,軟件注冊模板提取用戶機器的特定信息(如:MAC地址、CPU序列號、硬盤序列號等等),並通過其它的編碼算法(如BASE64)生成一個申請碼C;
3. 用戶將申請碼C發給軟件供應商。軟件供應商通過注冊機采用私鑰D加密申請碼C后生成激活碼F。軟件供應商將激活碼F發給用戶。
4. 用戶輸入激活碼F,軟件注冊模板采用公鑰E對激活碼F解碼后生成G(即:用戶機器特征信息),然后軟件注冊模板提取用戶機器的特定信息后進行編碼。將編碼的結果與G進行比較,如果相等則用戶合法,完成授權,否則授權失敗。
4 實現方案
4.1 整體設計
4.1.1 概述
本文檔實現驗證碼驗證功能,以DLL(動態連接庫)的形式向應用程序提供驗證服務。如何處理授權驗證由應用程序本身來完成。
4.1.2 上下文定義 
上下文結構圖
說明:
Ø 驗證動態庫提供密鑰驗證,生成、編、解碼功能。
Ø 應用程序需要開發一個驗證模塊,通過調用驗證動態庫中的函數來進行驗證。
Ø 驗證動態庫本身不會提供提示信息展現和相關界面,因此,應用程序的驗證模塊需要提供某些操作和提示界面(例如:注冊碼輸入框、提示信息框等等)
模塊結構圖
說明:
Ø 驗證接口為一組WINAPI形式的API集,提供驗證相關的服務,由應用程序的驗證模塊調用。(C、C++、JAVA、DELPHI、VS.NET語言均可調用);
Ø 驗證功能模塊實現了具體的功能,由驗證接口API調用,向外提供服務,其本身不向外暴露;
Ø RSA算法模塊提供RSA算法實現,供驗證功能模塊調用;
Ø MD5算法模塊提供MD5算法實現,供驗證功能模塊調用;
Ø BASE64算法模塊提供BASE64算法實現,供驗證功能模塊調用;
Ø 注冊表操作模塊提供注冊表相關操作的實現,供驗證功能模塊調用;
Ø 文件操作模塊提供文件相關操作的實現,供驗證功能模塊調用
4.1.4 接口定義
4.1.4.1 IsLicensed函數
【功能說明】:判斷指定應用程序是否已經被授權
【原型定義】:BOOL WINAPI IsLicensed(LPCTSTR lpAppName=NULL);
【參數說明】:lpAppName:應用程序名稱,如果為空值(NULL),則驗證當前應程序
【返 回 值】:TRUE:已經被授權;FALSE:未被授權
【備 注】:無
4.1.4.2 GetActivationCode函數
【功能說明】:根據特征信息獲取激活碼
【原型定義】:BOOL WINAPI GetActivationCode(LPCTSTR lpCharacter,
LPCTSTR lpRegisterCode
UINT32 cbSize);
【參數說明】:lpCharacter:特征信息
lpRegisterCode:加密后的激活碼
cbSize: lpRegisterCode區域長度
【返 回 值】:TRUE:成功;FALSE:失敗
【備 注】:該功能供軟件注冊機調用
4.1.4.3 GetComputerCode函數
【功能說明】:獲取安裝計算的特征碼
【原型定義】:BOOL WINAPI GetComputerCode(LPCTSTR lpRegisterCode);
【參數說明】: lpRegisterCode:加密后的機器特征碼
【返 回 值】:TRUE:成功;FALSE:失敗
【備 注】:通過機器特征碼調用GetActivationCode函數可取得激活碼
4.1.4.4 GeneratorKeyFile函數
【功能說明】:產生密鑰文件
【原型定義】:BOOL WINAPI GeneratorKeyFile(LPCTSTR lpCharacter,
LPCTSTR lpKeyFile);
【參數說明】:lpCharacter: 特征信息,如果為空(NULL),則取計算的特征信息。
lpKeyFile:保存密鑰文件的名稱
【返 回 值】:TRUE:成功;FALSE:成功
【備 注】:該功能供軟件注冊機調用
4.1.4.5 ActivationByComputer函數
【功能說明】:根據機器特征碼激活系統
【原型定義】:BOOL WINAPI ActivationByComputer (LPCTSTR lpAcitveCode
,LPCTSTR lpAppName=NULL);
【參數說明】:lpAcitveCode:激活碼
lpAppName:應用程序名稱,如果為空值(NULL),則激活當前應程序
【返 回 值】:TRUE:激活成功;FALSE:激活失敗
【備 注】:因為機器特征碼可以由驗證模塊自動取得,因此不需要用戶輸入注冊碼
4.1.4.6 ActivationByCharacter函數
【功能說明】:根據輸入的特征激活系統
【原型定義】:BOOL WINAPI ActivationByCharacter(LPCTSTR lpCharacter,
LPCTSTR lpAcitveCode,
LPCTSTR lpAppName=NULL);
【參數說明】:lpCharacter:特征信息
lpAcitveCode:激活碼
lpAppName:應用程序名稱,如果為空值(NULL),則激活當前應程序
【返 回 值】:TRUE:激活成功;FALSE:激活成功
【備 注】:無
4.1.4.7 ActivationByFile函數
【功能說明】:根據密鑰文件激活系統
【原型定義】:BOOL WINAPI ActivationByFile(LPCTSTR lpKeyFile
LPCTSTR lpAppName=NULL);
【參數說明】:lpKeyFile:密鑰文件名稱
lpAppName:應用程序名稱,如果為空值(NULL),則激活當前應程序
【返 回 值】:TRUE:激活成功;FALSE:激活失敗
【備 注】:密鑰文件不但要包括計算特征碼,還要包括系統的激活碼。由於密鑰文件可以被多個系統使用,因此,安全性不是很高
4.1.4.8 GetEncryptKey函數
【功能說明】:獲取加密所采用的KEY
【原型定義】:BOOL WINAPI GetEncryptKey(LPCTSTR lpPublicKey,
UINT32 cbSize1,
LPCTSTR lpPrivateKey
UINT32 cbSize2);
【參數說明】:lpPublicKey:公鑰
cbSize1:公鑰長度
lpPrivateKey:私鑰
cbSize2:私鑰長度
【返 回 值】:TRUE:成功;FALSE:成功
【備 注】:該函數在發布到應用程序中時,需要禁用
4.1.4.9 SetEncryptKey函數
【功能說明】:設置加密所采用的KEY
【原型定義】:BOOL WINAPI SetEncryptKey(LPCTSTR lpPublicKey,
UINT32 cbSize1,
LPCTSTR lpPrivateKey
UINT32 cbSize2);
【參數說明】:lpPublicKey:公鑰
cbSize1:公鑰長度
lpPrivateKey:私鑰
cbSize2:私鑰長度
【返 回 值】:TRUE:成功;FALSE:成功
【備 注】:該函數在發布到應用程序中時,需要禁用