RSA
1. 简述
RSA(Rivest–Shamir–Adleman), 非对称密码算法,RSA加密算法是美国麻省理工学院的三位科学家 Rivest、Shamir、Adleman于1978年提出的, 简称RSA公钥密码系统。
理论基础: RSA算法的理论基础是数论的欧拉函数。
安全性: 对极大整数做因数分解的难度决定了 RSA 算法的可靠性。密钥越长,它就越难破解。截至 2022 年,已知被破解的最大 RSA 密钥是 829 位的 RSA-250。自 2015 年以来,NIST 建议 RSA 密钥长度至少为 2048 位。
用途: 数字签名、加密算法。作为加密算法使用的 RSA 会随着密钥长度增加,性能会急剧下降。
2. 数论基础
质数: 也称素数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
互质: 公约数只有1的两个整数,叫做互质整数。公约数只有1的两个自然数,叫做互质自然数。
整数分解: 也称质因数分解,是将一个正整数写成几个因数的乘积。因数分解的关键是寻找因子(约数),而完整的因子列表可以根据约数分解推导出,将幂从零不断增加直到等于这个数。
欧拉函数: 在数论,对正整数n,欧拉函数是小于等于n的正整数中与n互质的数的数目。
欧拉定理
3. 公私钥生成过程
Steps:
- Choose two different large random prime numbers say “p” and “q”.
- Calculate n = p * q. Since “n” is the modulus for the public key and the private keys
- Calculate the totient: Ø (n) = (p - 1)(q - 1)
- Choose an integer “e” such that 1 < e < Ø (n) and “e” is co-prime to Ø (n) i.e. “e” and Ø (n) share no factors other than 1.
- Find out decryption key “d” such that e * d = 1 mod (p - 1) (q - 1).
- Encrypt the message “m” using encryption key e, c = m^e mod n.
- Decrypt the message “m” using decryption key d, m = c^d mod n.
(加密消息、解密消息、签名消息等,网上有很多资料)
Java 中的 Key Pair
jdk java.security 包下的 KeyPairGenerator 类可用来生成 RSA 算法的公私钥
public static void main(String[] args) throws NoSuchAlgorithmException {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println(publicKeyString);
System.out.println(privateKeyString);
}
SSH Key Pair
1. 命令行生成密钥对
-
生成公私钥:
ssh-keygen -t rsa公钥:my_key.pub,私钥: my_key
-
校验公私钥是否匹配:
ssh-keygen -l -f my_keyssh-keygen -l -f my_key.pub如果二者生成的字符串一致,则说明公私钥是匹配的。
2. Java 生成密钥对
使用 jsch 生成 RSA 公钥、指纹、密钥
public static void main(String[] args) throws JSchException {
String comment = "gen rsa key pair";
KeyPair keyPair = KeyPair.genKeyPair(new JSch(), KeyPair.RSA);
ByteArrayOutputStream publicKeyOut = new ByteArrayOutputStream();
ByteArrayOutputStream privateKeyOut = new ByteArrayOutputStream();
keyPair.writePublicKey(publicKeyOut, comment);
keyPair.writePrivateKey(privateKeyOut);
String publicKey = publicKeyOut.toString();
String fingerPrint = keyPair.getFingerPrint();
String privateKey = privateKeyOut.toString();
System.out.println(publicKey);
System.out.println(fingerPrint);
System.out.println(privateKey);
}
参考: