RSA算法原理
RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
算法
(1)选择两个不同的大素数p和q;
(2)计算乘积n=pq和L=(p-1)(q-1);
(3)选择大于1小于L的随机整数E,使得gcd(E, L)=1,且1<e<L; 注:gcd即最大公约数;
(4)计算d使得d*e =1 mod L,且1<d<L;;注:即d*e mod L =1。
(5)对每一个密钥k=(n,p,q,d,e),定义加密变换为Ek(x)=xe mod n,解密变换为Dk(x)=yd mod n,这里x,y∈Zn;
(6)p,q销毁,以{e,n}为公开密钥,{d,n}为私有密钥。
算法演练:
1、假设 p=7,q=11(p,q 同为素数)则n=7*11 = 77;
2、L=(p-1)(q-1) = 6 * 10 = 60;
3、1<e<L, gcd(e,L)=1,即 1<e<60, gcd(e, 60)=1; 满足此条件的e有很多。 e = 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 49……59;
4、d*e mod Φ(n) =1, d * e mod 60 =1;
5、当 e = 7, d = 43
e = 11, d = 11
e = 13, d = 37
e = 19, d = 19
e = 23, d = 47
e = 29, d = 29
e = 31, d = 31
e = 37, d = 13
e = 37, d = 13
e = 41, d = 41
e = 49, d = 41
.
.
.
代码实现:
public class SimpleRSA {
/**
* 加密、解密算法
* @param key 公钥或密钥
* @param message 数据
* @return
*/
public static long rsa(int baseNum, int key, long message){
if(baseNum < 1 || key < 1){
return 0L;
}
//加密或者解密之后的数据
BigDecimal rsaMessage;
//加密核心算法(采用BigDecimal避免超过long最大值,丢失精度)\
//message的key次方 % baseNum
BigDecimal init = new BigDecimal(message + "");
BigDecimal message1 = new BigDecimal(message + "");
BigDecimal baseNum1 = new BigDecimal(baseNum + "");
for(int i = 1; i < key; i++){
init = message1.multiply(init);
}
rsaMessage = init.divideAndRemainder(baseNum1)[1];
long s = rsaMessage.longValue();
return s;
}
public static void main(String[] args){
//基数
int baseNum = 7*11;
//公钥
int keyE = 37;
//密钥
int keyD = 13;
//未加密的数据
long msg = 6L;
//加密后的数据
long encodeMsg = rsa(baseNum, keyE, msg);
//解密后的数据
long decodeMsg = rsa(baseNum, keyD, encodeMsg);
System.out.println("加密前:" + msg);
System.out.println("加密后:" + encodeMsg);
System.out.println("解密后:" + decodeMsg);
}
}
求解d
我们可以用代码来计算d的值
public class TestD {
public static void main(String[] args) {
// E * D mod L = 1
// L = 60; E=7,11,13,17,19,23,29,31,37,41
// 求D, D满足 1<D<L
int e = 41;
for(int i=0; i<60; i++){
if((i*e)%60==1){
System.out.println("d= "+i);
}
}
}
}