RSA加密算法的JAVA实现(基于BigInteger的api)
RSA的原理
密钥的生成
1.首先选取两个大素数p和q(比如每一个都有1024比特长);
2. 计算n = pq, z = (p-1)(q-1)
3. 随机选取加密密钥e(1
4. 选择d以致ed-1可以被z整除(也就是ed mod z = 1)
5. 公开钥为(e, n),秘密钥为(d, n)。
RSA的加密解密
有了公开密钥(e, n),私有密钥(d, n)
对原文m( m < n)加密,就是做如下的计算:
c = m^e mod n ——用 (e, n)加密m
对密文进行解密,就是做如下计算
m = c^d mod n ——用(d, n)解密c
代码如下
public class RSAUtil {
private final int bitLength = 1024;
private final BigInteger N;
private final BigInteger Z;
private final BigInteger E;
private final BigInteger D;
// 初始化所有需要的变量
public RSAUtil(){
BigInteger P,Q; // p,q 两个生成因子
/*
用BigInteger 的 api 生成定长的,可能是素数的 数
isProbablePrime 方法的参数 certainty 的解释:
如果该数是素数的概率超过了 1 - 1/2*certainty方法,则该方法返回 true 。执行时间正比于参数确定性的值
*/
while (!(P = BigInteger.probablePrime(bitLength,new SecureRandom())).isProbablePrime(256)){
continue;
}
while (!(Q = BigInteger.probablePrime(bitLength,new SecureRandom())).isProbablePrime(256)){
continue;
}
N = P.multiply(Q);
Z = lcm(P.subtract(BigInteger.ONE), Q.subtract(BigInteger.ONE));
E = pubKey();
D = privateKey();
}
// 计算a和b的最大公因数
public BigInteger gcd(BigInteger a, BigInteger b){
return a.gcd(b);
}
// 计算a和b的最大公约数
public BigInteger lcm(BigInteger a, BigInteger b){
BigInteger gcd = a.gcd(b);
return a.multiply(b).divide(gcd);
}
// 计算公钥E
public BigInteger pubKey(){
BigInteger e;
while ((e = BigInteger.probablePrime(bitLength - 1, new SecureRandom())).isProbablePrime(256)){
if(gcd(e,Z).equals(BigInteger.ONE))return e; //如果 e 和 z 的最大公约数为1,则满足公钥条件
}
return null;
}
// 计算私钥D
public BigInteger privateKey(){
/*
使用BigInteger的api找到模反元素(所谓模反就是存在一个整数d,可以使得ed被Z除的余数为1) this^-1 mod m
modInverse方法实质是在计算this^-1 mod m
*/
return E.modInverse(Z);
}
// 对小于等于1024长度的BigInteger进行加密(并没有加判断,请自行控制)
public BigInteger encrypt(BigInteger target){
/*
方法声明为modPow(BigInteger exponent, BigInteger m),实质是计算 this^exponent mod m
*/
return target.modPow(E,N);
}
//解密方法,与加密方法实现类似
public BigInteger decrypt(BigInteger target){
return target.modPow(D,N);
}
//测试
public static void main(String[] args) {
BigInteger test = new BigInteger("123456789");
RSAUtil rsaUtil = new RSAUtil();
BigInteger encrypt = rsaUtil.encrypt(test);
System.out.println("encrypt : " + encrypt);
BigInteger decrypt = rsaUtil.decrypt(encrypt);
System.out.println("decrypt : "+ decrypt);
}
}