一、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数组
成功~~