全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1881
推到 Plurk!
推到 Facebook!

如何用非對稱密碼演算法製作共用軟體的註冊碼

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-01-26 16:10:51 IP:61.64.xxx.xxx 未訂閱
此為轉貼資料 如何用非對稱密碼演算法製作共用軟體的註冊碼 來源: 超想軟件 -------------------------------------------------------------------------------- 網上大多數共用軟體的註冊碼(又稱?序列號)的設計都不是很好,比較容易被破解者做出註冊機來。下面介紹一種利用公鑰演算法(又稱?非對稱演算法)RSA製作註冊碼的方法。採用這種方法,不知道密鑰的話時很難寫出註冊機來。實際上有部分軟體已經使用了這類方法。 大家都知道RSA採用一對密鑰,即公鑰和私鑰,從公鑰難於推出私鑰,反之亦然,這個難度是基於大數分解的難度。利用RSA生成共用軟體註冊碼的思路如下: 1、先隨機生成一對公鑰E和私鑰D; 2、軟體作者自己寫一個註冊機,註冊機完成的工作就是把用戶名M用私鑰D加密,密文C就是註冊碼。由於密文往往包含不可顯示字元,所以最好把密文進行編碼,變成可顯示字元,比如採用base64、uuencode編碼等。 密文C = (M ^ D) mod N 其中^表示乘冪,mod表示求餘,N?RSA的模數。 3、共用軟體將用戶輸入的註冊碼先進行解碼(如base64解碼等),得到密文,然後用公鑰E對密文進行解密,得到明文M',如果明文和用戶名相同(即滿足M' = M),則說明註冊碼正確,否則就是非法的註冊碼。破解者可以通過跟蹤你的軟體得到公鑰E,但無法得到私鑰D。 明文M' = (C ^ E) mod D 有幾點需要說明: 1、模數N太短時不安全,容易被分解。以目前的計算能力,建議N取值在512-bit以上。但這樣註冊碼的長度也變長了,可能給用戶帶來不方便。一般要採用大數運算庫來實現RSA。 2、隨機生成密鑰對時,要採用盡可能好的亂數生成演算法,否則N還是很有可能被分解。 3、也可以在註冊機中用公鑰E對用戶名加密得到註冊碼,在軟體中對用戶輸入的註冊碼用私鑰D進行解密得到用戶名。此時公鑰E就不能取常用的3、65537等固定值,否則一旦被猜出E,則也可以寫出註冊機,因?此時破解者可以從你的軟體中得到私鑰D。 4、這種方法只是?了防止被人寫出註冊機,它無法防止通過修改程式中跳轉指令的方法來破解你的軟體。?了防止別人修改你的程式文件,可以用註冊碼中的一部分來加密你的程式碼或資料。 5、這種方法稍加改動即可防止正版用戶散發註冊碼,即採用一機一碼的方法,將用戶名替換成用戶機器的硬軟體資訊即可,這個硬軟體資訊應能唯一地表示用戶的機器,否則也容易被?造。 6、採用了上面的方法之後,只有知道至少一個合法註冊碼的人才能將程式破解。 下面舉一個例子,採用大數運算庫Freelip(http://www.und.nodak.edu/org/crypto/crypto/numbers/programs/freelip/freelip_1.1.tar.gz)來實現RSA。該庫是用C寫的,商業使用需要許可證。 1、首先隨機生成密鑰對。可以自己編程隨機搜索大素數。此處由於是舉例,我們採用RSATool(http://www.secretashell.com/TMG/RSATool2v15.zip)生成64-bit RSA的參數: 大素數P = A57F2B33, 大素數Q = E7C441B3, 模數N = 95D49FD119EF27A9, 私鑰D = 76D2A6E2AC86CC99, 公鑰E = 65537 2、製作註冊機。將用戶名用私鑰D進行加密,得到的密文作?註冊碼: 首先定義宏WIN32(VC自帶,但BCB中需要自己定義),然後包含頭文件"lip.h": #ifndef WIN32 #define WIN32 #endif #include "lip.h" 並把"lip.c"加入到project中。 然後將用戶名的ASCII碼轉換成相應的十六進位串: char UserName[] = "4E6574677579"; char SerialNumber[256]; verylong N = 0, D = 0, M = 0, C = 0; //Freelip中的大數類型?verylong。 zhsread( UserName, &M); //初始化明文M,M等於用戶名的十六進位表示 zhsread("95D49FD119EF27A9", &N); //初始化模數N zhsread("76D2A6E2AC86CC99", &D); //初始化私鑰D zexpmod(M, D, N, &C); //計算密文C = (M ^ D) mod N zswrite(SerialNumber, C); //將C的十進位串表示寫入SerialNumber中,即?註冊碼 3、在軟體中判斷註冊碼。 char UserNameString[ ] = "4E6574677579"; //用戶輸入的用戶名 char SerialNumber[ ] = "1876542098762625173846272838"; //用戶輸入的註冊碼 verylong N = 0, E = 0, C = 0, UserName = , DecryptedUserName = 0 ; zhsread(SerialNumber, &C); //初始化密文C zhsread("95D49FD119EF27A9", &N); //初始化模數N zsread("65537", &E); //初始化公鑰E zexpmod(C, E, N, &DecryptedUserName); //計算明文DecryptedUserName = (C ^ E) mod N zhsread(UserNameString, &UserName); //用戶輸入的用戶名 if (zcompare(UserName, DecryptedUsername)) { //錯誤的註冊碼 } else { //正確的註冊碼 } 附:常用的大數運算庫的地址(有些雖然不是專門的大數運算庫,但是帶有相關的庫) 1、Crypto :http://www.eskimo.com/~weidai/cryptlib.html(C ) 2、MIRACL:http://indigo.ie/~mscott/(C/C ) 3、GNU MP:http://www.swox.com/gmp/ (C) 4、Piologie: http://www.hipilib.de/pidownload.htm 5、cryptlib:http://www.cs.auckland.ac.nz/~pgut001/cryptlib/ 6、RSAEuro:http://www.rsaeuro.com/products/RSAEuro/ 7、OpenSSL:http://www.openssl.org/ 9、RSARef:http://download.gale.org/rsaref20.tar.Z 10、GInt:http://triade.studentenweb.org/GInt/gint.html (Delphi) ********************************************************* 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together! 希望能大家敞開心胸,將知識寶庫結合一起
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-05-11 22:35:51
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!