Java 中的 RSA 算法
# Java 中的 RSA 算法
前面讲解了 RSA 算法的原理,并讲了怎么手工加解密,现在我们来在编程语言中实践下吧!
在 Java 中,Java 标准库提供了 RSA 算法的实现。
# 示例
示例代码如下:
package chapter12Hash;
import java.math.BigInteger;
import java.security.*;
import javax.crypto.Cipher;
public class EncryptDemo5RSA {
public static void main(String[] args) throws Exception {
// 明文
byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");
// 创建公钥/私钥对:
Person alice = new Person("Alice");
// 用Alice的公钥加密:
byte[] pk = alice.getPublicKey();
System.out.println(String.format("public key: %x", new BigInteger(1, pk)));
byte[] encrypted = alice.encrypt(plain);
System.out.println(String.format("encrypted: %x", new BigInteger(1, encrypted)));
// 用Alice的私钥解密:
byte[] sk = alice.getPrivateKey();
System.out.println(String.format("private key: %x", new BigInteger(1, sk)));
byte[] decrypted = alice.decrypt(encrypted);
System.out.println(new String(decrypted, "UTF-8"));
}
}
class Person {
String name;
PrivateKey sk; //私钥
PublicKey pk; //公钥
public Person(String name) throws GeneralSecurityException{
this.name = name;
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
kpGen.initialize(1025);
KeyPair kp = kpGen.generateKeyPair();
this.sk = kp.getPrivate();
this.pk = kp.getPublic();
}
//把私钥导出为字节
public byte[] getPrivateKey() {
return this.sk.getEncoded();
}
// 把公钥导出为字节
public byte[] getPublicKey() {
return this.pk.getEncoded();
}
// 用公钥加密:
public byte[] encrypt(byte[] message) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, this.pk);
return cipher.doFinal(message);
}
// 用私钥解密:
public byte[] decrypt(byte[] input) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, this.sk);
return cipher.doFinal(input);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
RSA 的公钥和私钥都可以通过 getEncoded()
方法获得以 byte[]
表示的二进制数据,并根据需要保存到文件中。要从 byte[]
数组恢复公钥或私钥,可以这么写:
byte[] pkData = ...
byte[] skData = ...
KeyFactory kf = KeyFactory.getInstance("RSA");
// 恢复公钥:
X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pkData);
PublicKey pk = kf.generatePublic(pkSpec);
// 恢复私钥:
PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(skData);
PrivateKey sk = kf.generatePrivate(skSpec);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
以 RSA 算法为例,它的密钥有 256/512/1024/2048/4096 等不同的长度。长度越长,密码强度越大,当然计算速度也越慢。
如果修改待加密的 byte[]
数据的大小,可以发现,使用 512bit 的 RSA 加密时,明文长度不能超过 53 字节,使用 1024bit 的 RSA 加密时,明文长度不能超过 117 字节,这也是为什么使用 RSA 的时候,总是配合 AES 一起使用,即用 AES 加密任意长度的明文,用 RSA 加密 AES 口令。
上次更新: 2024/10/1 17:03:07