主要思想是提供者持有密鑰,通過RSA加密客戶端ID或時(shí)間戳離線注冊機(jī)開發(fā),加密成不那么難看的注冊碼,分發(fā)給客戶端。
客戶端解決后幻燈片電子相冊制作軟件(Photo D花紋心形筆刷下載3,通過其持有的公鑰驗(yàn)證注冊碼是否與本地標(biāo)識或時(shí)間戳一致。
一、 生成公鑰
ider = 新的 ider();
File.(".xml", .(true));
File.(".xml", .(false));
為了方便長期保存ThunderSoft GIF Maker(GIF動畫制作軟件),這里直接保存在文件中。
為了避免丟失客戶端的公鑰,我更喜歡將公鑰直接編譯到驗(yàn)證程序中離線注冊機(jī)開發(fā),但這也意味著如果更改了密鑰,舊的驗(yàn)證程序?qū)o法驗(yàn)證新生成的注冊碼。
二、 生成注冊碼
static string CreateRegCode(string mac, DateTime date) { RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider(); cryptor.FromXmlString(File.ReadAllText("PrivateKey.xml")); string signature = String.Format("[{}][{}]", mac, date.ToString("yyyy-MM-dd")); byte[] regCodeBytes = cryptor.SignData( Encoding.UTF.GetBytes(signature), "SHA"); return Convert.ToBaseString(regCodeBytes); }
該方法通過加密mac和日期的組合生成注冊碼。有幾點(diǎn)需要注意:
1.參數(shù)中的mac是客戶端機(jī)器的地址2.第四行的文件是上一步生成的key文件
3.由于只考慮認(rèn)證,客戶端也必須知道參數(shù)中的日期
三、 驗(yàn)證注冊碼
static bool Verify(string regCode) { const string PUBLIC_KEY = ""; try { RSACryptoServiceProvider cryptor = new RSACryptoServiceProvider(); cryptor.FromXmlString(PUBLIC_KEY); byte[] signedData = Convert.FromBaseString(regCode); bool today = cryptor.VerifyData( Encoding.UTF.GetBytes(String.Format("[{}][{}]", DateTime.Now.ToString("yyyy-MM-dd"))), "SHA", signedData); bool machineToday = cryptor.VerifyData( Encoding.UTF.GetBytes(String.Format("[{}][{}]", MAC, DateTime.Now.ToString("yyyy-MM-dd"))), "SHA", signedData); bool forever = cryptor.VerifyData( Encoding.UTF.GetBytes(String.Format("[{}][{}]", MAC, Environment.MachineName)), "SHA", signedData); return today || machineToday || forever; } catch { return false; } }
此方法驗(yàn)證三種類型的注冊碼:今天可用、今天在機(jī)器上可用和永遠(yuǎn)可用。
需要注意:
1.第三行的公鑰是第一步的.xml中的內(nèi)容
第 14 行和第 17 行中的 2.mac 是客戶端計(jì)算機(jī)的物理地址。如何獲取不是本文的重點(diǎn),請自行百度。
3.考慮到客戶端填寫的注冊碼可能不是合法文本,需要在解析時(shí)捕獲異常
其實(shí)ider也提供了解密的方法,可以驗(yàn)證更多類型的驗(yàn)證碼。