RSA算法——由三位发明者Ronald Rivest、Adi Shamir 和 Leonard Adleman 姓氏的首字母拼在一起组成。
RSA算法属于“公开密钥加密技术”,其加密和解密的秘钥不同。
用于加密的密钥可以公开,因此称为“公钥”,而用于解密的密钥是只有自己才知道,称为“私钥”。
简单算法如下所示:
#####创建公钥#####
(1)选两个质数a,b。
如:a=13,b=29
(2)求c=a*b。
如:c=377
(3)求d=(a-1)*(b-1)
如:d=336
(4)选择和d没有公约数的e
如:e = 5
(5)得到公钥(c,e)
PublicKey [c=377, e=5]
#####创建私钥#####
(1)求出f,使其满足(f*e)÷d余1
如:f=269
(2)得到私钥(c,f)
PrivateKey [c=377, f=269]
###使用公钥加密:密文 =((明文的e次方)÷c)的余数
###使用私钥解密:明文 =((密文的f次方)÷c)的余数
代码:
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; class PublicKey {
int c;
int e; @Override
public String toString() {
return "PublicKey [c=" + c + ", e=" + e + "]";
}
} class PrivateKey {
int c;
int f; @Override
public String toString() {
return "PrivateKey [c=" + c + ", f=" + f + "]";
}
} /**
*
* @author Andy Hoo
*
*/
public class RSA {
PublicKey publicKey = new PublicKey();
PrivateKey privateKey = new PrivateKey(); public void mKey() {
System.out.println("#####创建公钥#####");
System.out.println("(1)选两个质数a,b。");
int a = 13, b = 29;
System.out.println(" 如:a=" + a + ",b=" + b);
System.out.println("(2)求c=a*b。");
int c = a * b;
System.out.println(" 如:c=" + c);
System.out.println("(3)求d=(a-1)*(b-1)");
int d = (a - 1) * (b - 1);
System.out.println(" 如:d=" + d);
System.out.println("(4)选择和d没有公约数的e");
int e;
for (e = 2; e < d; e++) {
if (!getCommonDivisor(d, e)) {
break;
}
}
System.out.println(" 如:e = " + e); System.out.println("(5)得到公钥(c,e)");
publicKey.c = c;
publicKey.e = e;
System.out.println(publicKey); System.out.println("#####创建私钥#####");
System.out.println("(1)求出f,使其满足(f*e)÷d余1");
int f = 0;
for (f = 1; f <= d; f++) {
if ((f * e) % d == 1) {
System.out.println(" 如:f=" + f);
break;
}
}
System.out.println("(2)得到私钥(c,f)");
privateKey.c = c;
privateKey.f = f;
System.out.println(privateKey);
} /**
* 加密
*
* @param original原文
* @return 密文
*/
public int encrypt(int original) {
System.out.println("###使用公钥加密:密文 =((明文的e次方)÷c)的余数");
int cryptograph = powAndRemainder(original, publicKey.e, publicKey.c);
return cryptograph;
} /**
* 解密
*
* @param cryptograph密文
*/
public int decrypt(int cryptograph) {
System.out.println("###使用私钥解密:明文 =((密文的f次方)÷c)的余数");
int after = powAndRemainder(cryptograph, privateKey.f, privateKey.c);
return after;
} /**
* 加密解密通用方法: (a的b次方)%c
*/
public static int powAndRemainder(int a, int b, int c) {
BigDecimal bd = new BigDecimal(a);
// 求幂
BigDecimal bd2 = bd.pow(b);
// 取余数
BigDecimal[] dr = bd2.divideAndRemainder(new BigDecimal(c));
return dr[1].intValue();
} /**
* 求公约数
*
* @param a1
* @param a2
* @return true有公约数/false没有公约数
*/
public static boolean getCommonDivisor(int a1, int a2) {
List<Integer> commonDivisor = new ArrayList<Integer>();
int min = Math.min(a1, a2);
for (int n = 2; n <= min; n++) {
if (a1 % n == 0 && a2 % n == 0) {
commonDivisor.add(n);
}
}
if (commonDivisor.size() != 0) {
System.out.println(a1 + "," + a2 + "有公约数" + commonDivisor);
return true;
} else {
System.out.println(a1 + "," + a2 + "没有公约数");
return false;
}
} public static void main(String[] args) {
RSA rsa = new RSA();
// 获取秘钥
rsa.mKey();
// 原文
int original = 101;
System.out.println("原文:" + original);
// 加密
int cryptograph = rsa.encrypt(original);
System.out.println("密文:" + cryptograph);
// 解密
int after = rsa.decrypt(cryptograph);
System.out.println("解密后:" + after);
}
}