RSA算法实例
RSA算法是一种非对称加密的方式,这种方式采用公私钥对的方式来对文件进行加解密,这种算法的效率相较于对称加密的效率较低,但是安全性较高,一般在应用中RSA算法一般用于密钥的加密,而真正的加密交给AES这一类的对称秘钥来完成。
RSA算法主要包括以下5步
1. 随机选择两个不相等的质数p和q
2. 计算p和q的乘积n,n的长度就是密钥长度
3. 计算欧拉函数 φ(n) = (p-1)(q-1)
4. 随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质
5. 计算e对于φ(n)的模反元素d。
用java代码来实现以上的过程(可直接下载源文件)
package rsa;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Date;
import java.util.Random;
public class tuRSA {
/**
* p,q-两个质数 n-p,q乘积
*
* @param args
* @throws UnsupportedEncodingException
*/
public static void main(String[] args) throws UnsupportedEncodingException {
// 1.随机选择两个不相等的质数p和q
BigInteger p = BigInteger.probablePrime(1024, new Random(new Date().getTime()));
BigInteger q = BigInteger.probablePrime(1024, new Random(new Date().getTime()));
System.err.print("p:");
System.out.println(p);
System.err.print("q:");
System.out.println(q);
// 2.计算p和q的乘积n,n的长度就是密钥长度
BigInteger n = p.multiply(q);
System.err.print("n:");
System.out.println(n);
// 3.计算欧拉函数 φ(n) = (p-1)(q-1)
BigInteger fai = p.subtract(new BigInteger("1")).multiply(q.subtract(new BigInteger("1")));
System.err.print("fai:");
System.out.println(fai);
// 4.随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质
BigInteger e = getE(fai);
System.err.print("e:");
System.out.println(e);
// 5.计算e对于φ(n)的模反元素d。
BigInteger d = getD(fai, e);
System.err.print("d:");
System.out.println(d);
String content = "123";
System.err.print("c:");
System.out.println(content);
String encrypt = encrypt(content, n, e);
System.err.print("encrypt:");
System.out.println(encrypt);
String decode = decode(encrypt, d, n);
System.err.print("decode:");
System.out.println(decode);
}
/**
* 随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质,互质数之间的最大公约数是1。/gcd 最大公约数/ signnum 正负号函数,
*
* @param fai
* @return
*/
public static BigInteger getE(BigInteger fai) {
boolean isGcd = false;
boolean isSmall = false;
BigInteger e = null;
do {
e = new BigInteger(10, new Random());// 2的10次
isGcd = e.gcd(fai).toString().equals("1");// 最大公约数是否等于1
isSmall = e.subtract(fai).signum() == -1;// 是否小于fai
} while (e.toString().equals("1") || !isGcd || !isSmall); // isGcd:true+isSmall:true+false 跳出
return e;
}
/**
* 所谓"模反元素"就是指有一个整数d,可以使得ed被φ(n)除的余数为1。 ed ≡ 1 (mod φ(n)) 这个式子等价于 ed - 1 = kφ(n)
* 于是,找到模反元素d,实质上就是对下面这个二元一次方程求解。 ex + φ(n)y = 1 已知 e=17, φ(n)=3120, 17x +
* 3120y= 1
*
* @param fai
* @param e
* @return
*/
private static BigInteger getD(BigInteger fai, BigInteger e) {
// ed-kφ(n)=1
BigInteger k;
for (int k1 = 2;; k1++) {
BigInteger tt = new BigInteger(String.valueOf(k1)).multiply(fai).add(new BigInteger("1"));
if (tt.mod(e).toString().equals("0")) {
k = new BigInteger(String.valueOf(k1));
break;
}
}
return fai.multiply(k).add(new BigInteger("1")).divide(e);// 求d=(k*fn+1)/e
}
/**
* 解密m=c^d mod n
*
* @param content
* @param n
* @param e
*/
public static String decode(String content, BigInteger d, BigInteger n) {
BigInteger m = null;
m = new BigInteger(content).modPow(d, n);
return m.toString();
}
/**
* 加密c = m^e mod n
*
* @param content
* 原文
* @param n
* p和q的乘积
* @param e
* @return
*/
public static String encrypt(String content, BigInteger n, BigInteger e) {
BigInteger c = null;
c = new BigInteger(content).modPow(e, n);// content^e mod n
return c.toString();
}
}
最后得到结果