RSA算法Java的简单实现
RSA简介
RSA算法据说是⽬前地球上最重要的加密算法。是这么介绍的:“对极⼤整数做因数分解的难度决定了RSA算法的可靠性。换⾔之,对⼀极⼤整数做因数分解愈困难,RSA算法愈可靠。假如有⼈到⼀种快速因数分解的算法,那么RSA的可靠性就会极度下降。但到这样的算法的可能性是⾮常⼩的。今天只有短的RSA密钥才可能被暴⼒破解。到2008年为⽌,世界上还没有任何可靠的攻击RSA算法的⽅式。只要密钥长度⾜够长,⽤RSA加密的信息实际上是不能被解破的。”
看上去很神奇是吧,其实在学习⽹络安全和密码学这门课的时候,都接触过。毕业近⼀年了,数论⽅⾯的知识忘的差不多了。如果⼤家对RSA算法原理很感兴趣,推荐下⾯这两篇⽂章:
本⽂描述下,我⾃⼰实现的⼀个简单的RSA算法。
RSA密钥⽣成和加密解密过程
RSA的具体实现
RSA具体实现的难点在于质数的⽣成。好在Java提供了⼀个强⼤的⼯具类BigInteger。具体的实现如
(不过百⾏):
public class RSA {
private BigInteger p = null;
private BigInteger q = null;
private BigInteger n = null;
private BigInteger totient = null;
private BigInteger e = null;
private BigInteger d = null;
public RSA(BigInteger p, BigInteger q) {
this.p = p;
this.q = q;
n = p.multiply(q); // n = p * q;//totient =(p-1)*(q-1)即 (n)
totient = (p.subtract(BigInteger.valueOf(1)).multiply((q
.subtract(BigInteger.valueOf(1)))));
e = getE();//选择公钥
BigInteger y = egcd(totient, e)[1];
d = y.mod(totient); //产⽣私钥
}
public BigInteger getE() {
// 这⾥以totient/4为种⼦,选取⼀个素数作为公钥
return totient.divide(BigInteger.valueOf(4)).nextProbablePrime();
}
// 扩展的Euclid算法,⽬的:算出e-1 mod n
public static BigInteger[] egcd(BigInteger d1, BigInteger d2) {
BigInteger[] ret = new BigInteger[3];
BigInteger u = BigInteger.valueOf(1), u1 = BigInteger.valueOf(0);
BigInteger v = BigInteger.valueOf(0), v1 = BigInteger.valueOf(1);
if (d2pareTo(d1) > 0) {
BigInteger tem = d1;
d1 = d2;
d2 = tem;
}
while (d2pareTo(BigInteger.valueOf(0)) != 0) {
BigInteger tq = d1.divide(d2); // tq = d1 / d2
BigInteger tu = u;
u = u1;
u1 = tu.subtract(tq.multiply(u1)); // u1 =tu - tq * u1
BigInteger tv = v;
v = v1;
v1 = tv.subtract(tq.multiply(v1)); // v1 = tv - tq * v1
BigInteger td1 = d1;
d1 = d2;
d2 = td1.subtract(tq.multiply(d2)); // d2 = td1 - tq * d2
ret[0] = u;
ret[1] = v;
ret[2] = d1;
}
return ret;
}
// 加密
public BigInteger encode(BigInteger d) {
dPow(this.e, this.n);
}
// 解密
public BigInteger decode(BigInteger c) {
dPow(this.d, this.n);
}
}
RSA的缺点
java源代码加密
RSA算法使⽤乘⽅运算,明⽂以分组为单位进⾏加密,每个分组的⼆进制值均⼩于n也就是说分组的⼤⼩必须⼩于或等于log2(n)+1位。如果明⽂分组⼤于此长度,则需要进⼀步细分,或者借助另外⼀种对称的加密算法来进⾏加密。此外,RSA加密解密效率不⾼,特别是密钥长度很长的时候,不适合对⼤量信息进⾏加密。所以⼀般RSA会和其他对称的加密算法配合使⽤。
下⾯是我本科毕设中设计的⼀个简单的加密⽅案,以及前⼏天根据这个⽅案写的⼀个demo。
假设客户端要向服务发送数据,⾸先客户端需要通过⽤户名和密码⽣成⾃⼰的RSA密钥(⽤于解密的私
钥cPR),然后通过⼀个随机数⽣成这次数据传输的DES密钥deskey_c,除此之外我们还知道服务端的RSA公钥sPU(服务端的RSA密钥是固定的)。有了这次数据传输的密钥信息之后,客户端就可以将数
据M1通过DES算法⽤deskey_c加密得到密⽂C1,然后将客户端⽣成的DES密钥deskey_c通过RSA算法⽤服务端的公钥sPU加密得到加密后的DES密钥c_deskey_c。最后将加密后的信息(密⽂C1和加密后的DES密钥c_deskey_c)通过http协议发送到服务端。服务端接收后,先通过⾃⼰的私钥sPR将DES密钥解密出来,得到之前客户端⽣成的deskey_c,然后通过DES算法⽤deskey_c解密C1,得到原来的数据M1。⾄此,客户端加密服务端解密的过程结束。在加密解密过程中,DES密钥为50位10进制数,RSA
算法中的p和q的范围是0到150位⼗进制整数。⽽当服务端向客户端发送数据的时候,同样需要⽣成密钥信息。⾸先服务端通过客户端的⽤户名和密码得到客户端的RSA公钥cPU,然后通过⼀个随机数得到这
次数据传输的DES密钥deskey_s,然后通过DES算法⽤deskey_s将数据M2加密为密⽂C2,然后通过RSA算法⽤客户端的公钥cPU将deskey_s加密为c_deskey_s。最后服务端将密⽂C2和加密后的DES
密钥c_deskey_s发送给客户端。客户端接收后,先通过RSA算法⽤⾃⼰的私钥cPR解密c_deskey_s,
得到原来服务端⽣成的DES密钥deskey_s,然后通过DES算法⽤该密钥解密出原来的数据M2。这样
就完成了服务端加密,客户端解密的过程。
Demo:
附上⼯程源码(最近加班紧,代码写的不是很好-_-||):

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。