RSA協(xié)議我不再描述,大家可以看http://www.di-mgt.com.au/rsa_alg.html。
RSA的密鑰對生成時(shí)間依賴(lài)于兩個(gè)因素,
第一,密鑰的長(cháng)度
第二,素數的篩選質(zhì)量
在整個(gè)密鑰對生成過(guò)程中,RSA會(huì )隨機選擇兩個(gè)大素數,事實(shí)上,計算機的聰明
程度還不足以判斷某個(gè)隨機選擇的大素數是否真的不可分解,因此,你只能夠通過(guò)
計算機程序來(lái)盡量將這個(gè)大隨機數不是素數的幾率降到某個(gè)界限值(如0.0001)以下。
RSA KeyPair分為公鑰和私鑰,你應該這樣使用KeyPair:
1,你使用私鑰來(lái)簽名,別人用你的公鑰來(lái)驗證簽名
2,別人用你的公鑰加密信息M->M‘,你用私鑰來(lái)解密信息M‘->M
雖然RSA經(jīng)受過(guò)多年深入的密碼分析,但大家在使用RSA的時(shí)候還是要注意以下事項,
否則RSA的安全性會(huì )大打折扣:
1,合理的密鑰長(cháng)度(setKeyLength)
RSA1024至今是安全的,按照目前密碼分析和計算機硬件條件的發(fā)展,估計在未來(lái)5-10年,
仍以難以破解。
2,素數確定性選擇(setCertaintyOfPrime)
實(shí)際應用中,選擇100就行了。
3,選擇合理的padding(setRSAMode)
RSA有三種模式,RAW, PKCS和OAEP,日常應用中,我本人只使用PKCS(PKCS#1 v1.5)
和OAEP(PKCS#1 v2.0)這兩種padding模式。
padding跟安全性其實(shí)是緊密掛鉤的,有興趣的朋友可以看看PKCS#1標準討論。
我編寫(xiě)了一個(gè)RSAUtils的工具類(lèi),下面的該類(lèi)的測試代碼的一部分。
程序如下:
RSAUtils utils =new RSAUtils();
utils.setKeyLength(1024);
utils.setCertaintyOfPrime(100);
utils.setRSAMode(PKCS_RSA_MODE); //RAW =1 PKCS=2 OAEP=3
utils.initRSAKeyPair();
//查看公鑰
RSAKeyParameters mypubkey=utils.getPublicKey();
BigInteger mypubkey_modulus=mypubkey.getModulus();
BigInteger mypubkey_exponent=mypubkey.getExponent();
System.out.println("##mypubkey的modulus長(cháng)度="+mypubkey_modulus.bitLength());
System.out.println("##mypubkey_modulus值="+mypubkey_modulus.toString());
System.out.println("##mypubkey的exponent長(cháng)度="+mypubkey.getExponent().bitLength());
System.out.println("##mypubkey_exponent值="+mypubkey_exponent.toString());
//查看私鑰
RSAKeyParameters myprivkey=utils.getPrivateKey();
BigInteger myprivkey_modulus=myprivkey.getModulus();
System.out.println("##myprivkey的modulus長(cháng)度="+myprivkey_modulus.bitLength());
System.out.println("##myprivkey的modulus值="+myprivkey_modulus.toString());
System.out.println("##myprivkey.getExponent()長(cháng)度="+myprivkey.getExponent().bitLength());
System.out.println("##myprivkey.getExponent()值="+myprivkey.getExponent());
以下是輸出:
##mypubkey的modulus長(cháng)度=1024
##mypubkey_modulus值=93806062666699782638132820491933031482836826566660997927543724649365705
443512121003172409185855121369631538039111403612211728268332662414248776212969019881724066
05508032773596521836539959532320010943647214725811041746982574818113114921761380678031837
4365617984326523029965066348377550281908277056378455106547
##mypubkey的exponent長(cháng)度=2
##mypubkey_exponent值=3
##myprivkey的modulus長(cháng)度=1024
##myprivkey的modulus值=93806062666699782638132820491933031482836826566660997927543724649365
70544351212100317240918585512136963153803911140361221172826833266241424877621296901988172
40660550803277359652183653995953232001094364721472581104174698257481811311492176138067803
18374365617984326523029965066348377550281908277056378455106547
##myprivkey.getExponent()長(cháng)度=1023
##myprivkey.getExponent()值=6253737511113318842542188032795535432189121771110733195169581643
29104702956747473354482727905700809130876920260742690748078188455551082761658508086460132
41363962278455328383552959397735977285649455021534046301135296075808377308404258909132811
288204167107604525033796313576612747649866739561523887875979483707
其中,要記住,公鑰的exponent即RSA算法中的e, e通常是3,17和65537
X.509建議使用65537,PEM建議使用3,PKCS#1建議使用3或65537,一般來(lái)說(shuō),都是選擇3。
私鑰的Exponent就是私鑰中最重要的部分,它就是私鑰區別于公鑰的地方!
接著(zhù),我們看看RSA的加密,解密過(guò)程。
通常,不要隨便對某一個(gè)別人發(fā)過(guò)來(lái)的東西進(jìn)行簽名(有潛在危險),即使有這樣的必要,請先將它的文件進(jìn)行Digest或者HMAC
處理后,再做簽名。
為了說(shuō)明RSA是如何加密信息的,我先讓大家脫離MD5/SHA1等輔助算法(沒(méi)有人會(huì )單獨使用RSA,RSAwithMD5,RSAwithSHA1才是常用
的使用方法),來(lái)單獨看看RSA本身:
大家習慣了DES/IDEA,再看RSA的加密,可能會(huì )有一些不習慣,因為RSA雖然也可以看成是基于Block的加密,但是,RSA的輸入和輸出的Block的
大小是不一樣的,Block的大小依賴(lài)于你所使用的RSA Key的長(cháng)度和RSA的padding模式。
在RSAUtils測試用例中,分別對RSA設置三種長(cháng)度的Key(768,1024,2048)和2種padding模式(PKCS 1.5和OAEP),結果如下:
RSA InBlock大小 OutBlock大小 (單位,字節)
768bit/PKCS 85 96
1024bit/PKCS 117 128
2048bit/PKCS 245 256
768bit/OAEP 54 96
1024bit/OAEP 86 128
2048bit/OAEP 214 256
大家可以看到,相同密鑰長(cháng)度, 加密出來(lái)的密文長(cháng)度要比明文要長(cháng),且OAEP的InBlock/OutBlock要比PKCS的InBlock/OutBlock要小,單從
熵的角度,意味著(zhù)OAEP padding模式引入更多的熵,OAEP要比PKCS更安全(事實(shí)上,為何提出OAEP代替PKCS,大家可以到RSA網(wǎng)站看看
OAEP文檔 http://www.rsasecurity.com/rsalabs/node.asp?id=2125)。
下面,RSAUtils是我寫(xiě)的針對BouncyCastle的一個(gè)工具類(lèi),它封裝了BouncyCastle的crypto中的RSAEngine,基本上,我很少單獨使用
RSAUtils,我更多的是結合DiegestUtils來(lái)使用。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。