推薦+1置頂+1(分享、討論、實現)通用軟件注冊功能之建立有效的軟件保護機制


推薦+1置頂+1分享、討論、實現)

通用軟件注冊功能之建立有效的軟件保護機制

 

         眾所周知,一些共享軟件往往提供給使用者的是一個功能不受限制的限時使用版,在試用期內使用者可以無限制的使用軟件的全部功能(只是可能會出現提示使用者注冊的窗口),試用期一過部分(或全部)功能失效,要想繼續使用只能向作者索取注冊碼(或注冊文件)完成對軟件的合法注冊,注冊后的軟件將解除一切使用限制。如果您也開發出一個有價值的作品,是否也希望為自己的軟件增加一個這樣的功能呢?當前對於.NET反編譯的問題不在本文討論之內,相關文章已經很多!本文我們就一起探討軟件注冊功能的實現。

       實現軟件的注冊功能方法很多,最需要考慮的就是不能輕易的讓使用者破解,在這里,我就談談“.NET快速開發整合框架(RDIFramework.NET)”中平台注冊功能的實現方法。在RDIFramework.NET中,注冊功能主要方法就是對計算機唯一硬件信息進行RSA數字簽名達到軟件注冊和保護的功能,該方法實現簡單,安全性相應較高。

       計算機唯一硬件信息(我們知道計算機中的關鍵部件如CPU,主板等在全球范圍內都有一個獨一無二的產品序列號,用戶通過注冊模塊獲取這些產品序列號(即傳統所說的:機器嗎)並將它發送給軟件開發商要求進行RSA數據簽名,軟件開發商獲得這些機器碼后利用手中的私鑰對這些信息進行RSA數字簽名,生成的簽名信息(即注冊碼)發回給用戶,用戶將收到的注冊碼輸入注冊模塊的注冊碼框,軟件即可利用公鑰執行簽名驗證,如果輸入的注冊碼被證明就是經過開發商數字簽名的機器碼,則完成注冊過程。

       注冊功能項目結構圖如下所示:

 

圖1 注冊功能項目結構

 

平台服務端注冊碼生成主界面如下所示:

 

圖2 注冊文件管理器

通過“注冊文件管理器”,我們就可以根據用戶提供的信息來生成軟件的注冊文件。

客戶端的注冊主要就是根據我們提供的注冊文件與公鑰,來驗證注冊文件是否為當前客戶的有效注冊文件,如果有效,注冊成功,無效則注冊失敗!客戶端注冊功能設計參考如下所示:

 

圖3 平台注冊

用戶單擊“注冊”按鈕,成功注冊提示:

 

圖4注冊成功

服務端注冊碼生成核心代碼:

一、     生成公/私鑰文件:

 

 1 private void btnGenerateKey_Click(object sender, EventArgs e)
 2         {
 3             if (MessageBox.Show("確定生成生成公/私鑰對嗎(是/否)?", "詢問信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) 
 4                 == System.Windows.Forms.DialogResult.Cancel)
 5             {
 6                 return;
 7             }
 8 
 9             RSACryptoServiceProvider crypt = new RSACryptoServiceProvider();
10          
11             string publicKey = crypt.ToXmlString(true);
12             string privateKey   = crypt.ToXmlString(false);
13             crypt.Clear();
14 
15             //生成公鑰
16             using (StreamWriter sw = new StreamWriter(KeyPath + "RDIFrameworkkey.key", false, UTF8Encoding.UTF8))
17             {
18                 sw.Write(SecretHelper.AESEncrypt(publicKey));
19                 sw.Flush();
20             }
21 
22             //生成私鑰
23             using (StreamWriter sw = new StreamWriter(KeyPath + "RDIFrameworkPrivateKey.key", false, UTF8Encoding.UTF8))
24             {
25                 sw.Write(SecretHelper.AESEncrypt(privateKey));
26                 sw.Flush();
27             }           
28           
29             MessageBox.Show("成功生成公/私鑰對!","提示信息",MessageBoxButtons.OK,MessageBoxIcon.Information);
30         }

二、     生成注冊文件:

 1 private void btnGenerateRegisterFile_Click(object sender, EventArgs e)
 2         {
 3             if (string.IsNullOrEmpty(txtUserEmail.Text.Trim()))
 4             {
 5                 MessageBox.Show("用戶郵箱不能為空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
 6                 txtUserEmail.Focus();
 7                 return;
 8             }
 9             else
10             {
11                 if (!RegexValidatorHelper.IsMatch(txtUserEmail.Text.Trim(), Pattern.EMAIL))
12                 {
13                     MessageBox.Show("郵箱格式不正確!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
14                     txtUserEmail.SelectAll();
15                     return;
16                 }
17             }
18 
19             if (string.IsNullOrEmpty(txtCPUSerialNo.Text.Trim()))
20             {
21                 MessageBox.Show("CPU序列號不能為空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
22                 return;
23             }
24 
25             if (!string.IsNullOrEmpty(txtUseLimited.Text.Trim()))
26             {
27                 if (!RegexValidatorHelper.IsMatch(txtUseLimited.Text.Trim(), Pattern.INTEGER))
28                 {
29                     MessageBox.Show("使用次數應該為數值型!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
30                     txtUseLimited.SelectAll();
31                     return;
32                 }
33             }
34 
35             //讀取私鑰
36             StreamReader sr = new StreamReader(KeyPath + "RDIFrameworkPrivateKey.key", UTF8Encoding.UTF8);            
37             string keypair = sr.ReadToEnd();
38             sr.Close();
39 
40             //用私鑰參數初始化RSACryptoServiceProvider類的實例crypt。
41             RSACryptoServiceProvider crypt = new RSACryptoServiceProvider();
42 
43             crypt.FromXmlString(SecretHelper.AESDecrypt(keypair));
44 
45             UTF8Encoding enc = new UTF8Encoding();
46 
47             string trialTime = "30";//試用次數(默認:30數,0:表示永久)
48             if (!string.IsNullOrEmpty(txtUseLimited.Text.Trim()))
49             {
50                 trialTime = txtUseLimited.Text.Trim();
51             }
52             string regInfo = txtUserEmail.Text.Trim() + ";" + txtMAC.Text.Trim() + ";" + txtCPUSerialNo.Text.Trim() + ";" + trialTime;
53 
54             byte[] bytes = enc.GetBytes(regInfo);//格式:郵箱地址;MAC;CPU序列號;試用時間
55             //對用戶信息加密
56             bytes = crypt.Encrypt(bytes, false);
57             
58             //生成注冊數據,對二進制字節進行Base64編碼,但采用注冊文件的形式的進修也可以不做此轉化。
59             string encrytText = System.Convert.ToBase64String(bytes, 0, bytes.Length);
60 
61             //將注冊碼寫入文件
62             using (StreamWriter sw = new StreamWriter(KeyPath + "RDIFramework_reg_file.lic", false, UTF8Encoding.UTF8))
63             {
64                 sw.Write(encrytText);
65                 sw.Flush();
66             }
67 
68             MessageBox.Show("注冊文件:RDIFramework_reg_file.lic生成成功!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);         
69         }

三、     驗證注冊文件:

 

 1 private void btnCheckRegistr_Click(object sender, EventArgs e)
 2         {
 3             //讀取注冊數據文件
 4             StreamReader sr = new StreamReader(KeyPath + "RDIFramework_reg_file.lic", UTF8Encoding.UTF8);
 5             string encrytText = sr.ReadToEnd();
 6             sr.Close();
 7 
 8 
 9             //讀取公鑰
10             StreamReader srPublickey = new StreamReader(KeyPath + "RDIFrameworkkey.key", UTF8Encoding.UTF8);
11             string publicKey = srPublickey.ReadToEnd();
12             srPublickey.Close();
13 
14             //用公鑰初化始RSACryptoServiceProvider類實例crypt。
15             RSACryptoServiceProvider crypt = new RSACryptoServiceProvider();
16             crypt.FromXmlString(SecretHelper.AESDecrypt(publicKey));
17             UTF8Encoding enc = new UTF8Encoding();
18             byte[] decryptByte;
19             try
20             {
21                 byte[] newBytes;
22                 newBytes = System.Convert.FromBase64CharArray(encrytText.ToCharArray(), 0, encrytText.Length);
23                 decryptByte = crypt.Decrypt(newBytes, false);
24                 string decrypttext = enc.GetString(decryptByte);
25                 //
26                 //TODO:在此處添加驗證邏輯
27                 //
28                 MessageBox.Show(decrypttext);
29             }
30             catch(Exception ex)
31             {
32                 MessageBox.Show(ex.Message);
33             }
34         }

 

至此,軟件的注冊功能就完成了,當然還有其他很多方法,比如:

一、 采用加密狗的方式(最安全的方式)。

二、 在線驗證注冊信息(用戶需能上網),這種方式也比較可靠。

三、 其他方法,歡迎大家討論。

四、  ......

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM