一、RSA算法
1.密鑰生成
- 隨機生成兩個大素數p、q
- 計算n=p*q
- 計算n的歐拉函數f=(p-1)*(q-1)
- 選取1<e<f,使e與f互素
- 計算d,ed=1modf
- 公鑰為(e,n),私鑰為(d,n)
2.加密
- c=m^e mod n
3.解密
- m=c^e mod n
二、BigInteger類(大數)
- 定義:
BigInteger b=new BigInteger("1");
- 將其他類型變量轉化為BigInteger變量
BigInteger b=BigInteger.valueof(1);
- 隨機生成大素數
BigInteger bigInteger = BigInteger.probablePrime(2048, r); //隨機生成2048位的大素數,r為Random變量
- 素性檢驗(米勒羅賓檢驗)
boolean a = b.isProbablePrime(256); //b是素數的概率為1 - 1 / 2^256
- 四則運算
BigInteger a,b,c;
c=a.add(b); //加
c=a.subtract(b); //減
c=a.multiply(b); //乘
c=a.divide(b); //除
- 最大公因子
BigInteger a,b,c;
c=a.gcd(b);
- 取余
BigInteger a,b,c;
c=a.remainder(b);
- 次方模(a^b mod m)
BigInteger a,b,c;
c=a.modPow(b,m);
三、算法實現
1.兩個大素數的生成
- 構建Big類,隨機生成大素數,並進行素性檢驗
2.公鑰生成
- 尋找與f互素的公鑰e(1<e<f)
3.私鑰生成
- 利用歐幾里得算法(輾轉相除法),列表,計算e模f的逆d
4.獲取密鑰
- 在Keys類中將公鑰、私鑰輸出到文件
5.加密
(1)從文件逐行讀取明文、公鑰
(2)使用getByte()
將明文轉化為byte數組
(3)依次計算c=m^e mod n
(4)將結果逐行輸出到文件
6.解密
(1)從文件逐行讀取密文、私鑰
(2)讀入密文的同時計算m=c^d mod n,並將其存入byte數組
(3)將byte數組還原為字符串(明文)
(4)輸出明文到文件
四、遇到的問題和解決方法
問題1:加密時不知道如何將明文轉化為可用於加密的數字
解決1:糾結了好久,想到看書時看到過的getByte()方法可以將字符串轉化為byte數組
問題2:解密時,出現了以下問題
解決2:這個錯誤還沒法調試,檢查了好久,發現自己計算公鑰e的時候模的是n,修改了成模f后,解決了該問題
問題3:之后,解密出來的文件還是有問題
解決3:調試后,發現自己犯了很蠢的錯誤,我把int i=0放在了while 循環里,每次循環都會把i置1...
問題4:然后,輸出還是有問題,后面會多一些空格
解決4:增加一個與明文長度等長的byte數組
成功~~