java 根据 KeyPairGenerator对象生成RS

java 根据 KeyPairGenerator对象生成RSA密钥对,并进行测试

说明:rsa 算法根据密钥长度, 每轮 加/解密 填充 允许的最大长度,也不相同,这个地方暂时还不知道是怎么计算出来的
限制:由于上面的原因,这里暂时只支持 密钥长度为 1024 / 2048 位长度
实现:根据 KeyPairGenerator 对象传入密钥长度,随机种子,生成rsa 密钥

编码实现

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
java复制代码	package com.example.demo.util.encrypt;

import org.apache.commons.codec.binary.Base64;
import sun.security.rsa.RSACore;
import sun.security.rsa.RSAKeyFactory;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
* 生成 rsa 密钥,通过 KeyPairGenerator 对象
*
* 尝试根据 密钥长度获取 每轮 加/解密 填充 允许的最大长度, 但是失败,先不尝试了
*/
public class RsaGenerate {


/**
* 解密 每轮的基准, 128 ,以 密钥 1024 位来算(与 私钥/公钥 解密无关)
*/
private static int decodePaddingBase = 128;

/**
* 加密 每轮的基准, 117 ,以 密钥1024 来算(与 私钥/公钥 加密无关)
*/
private static int encodePaddingBase = 117;


/**
* 密钥位数以 1024 位为基准
*/
private static int baseSize = 1024;





/**
* KeyFactory 不行
* KeyGenerator 不支持rsa
* @param args
* @throws NoSuchAlgorithmException
*/
public static void main(String[] args) throws Exception {
// 传入随机种子,生成 对称算法密钥对
int keySize = 1024;
String seedStr = "测试seed ajibahuihu";
String testStr = "这是一条测试数据,请注意 https://blog.csdn.net/kzcming";

process(keySize, seedStr, testStr);
}


/**
* 根据密钥的长度, 每轮 加/解密 填充 允许的最大长度,也不相同
* @param key
* @throws InvalidKeyException
*/
private static void makeSize(Key key) throws InvalidKeyException {
RSAKey var6 = RSAKeyFactory.toRSAKey(key);
int byteLength = RSACore.getByteLength(var6.getModulus());
if(key instanceof PrivateKey) encodePaddingBase = byteLength;
if(key instanceof PublicKey) decodePaddingBase = byteLength;

// if(key instanceof PrivateKey)
// init("1", key, JceSecurity.RANDOM,null);
}






private static void process(int keySize, String seedStr, String testStr) throws Exception {
KeyPair keyPair = getKeyPair(seedStr,keySize);
// 获得私钥,公钥
PrivateKey aPrivate = keyPair.getPrivate();
PublicKey aPublic = keyPair.getPublic();
byte[] privateEncoded = aPrivate.getEncoded();
byte[] publicEncoded = aPublic.getEncoded();
// Base64 编码
String privateKeyStr = Base64.encodeBase64String(privateEncoded);
String publicKeyStr = Base64.encodeBase64String(publicEncoded);
System.out.println("private:" + privateKeyStr);
System.out.println();
System.out.println("public:" + publicKeyStr);


// 执行测试
// int divide = keySize/baseSize;
// if( divide != 1 ) {
if(keySize == 2048) {
// makeSize(aPrivate);
// makeSize(aPublic);
encodePaddingBase = encodePaddingBase * 2;
decodePaddingBase = decodePaddingBase * 2;
}

// 公钥加密,私钥解密, 当然也可以反着,但是大家一般都这么弄
byte[] bytes = encryptByPublicKey(testStr.getBytes(), publicKeyStr);
byte[] bytes1 = decryptByPrivateKey(bytes, privateKeyStr);
System.out.println(new String(bytes1));
}

/**
* 获取对称加密密钥
*
* KeyPairGenerator 是生成对称加密密钥的 封装对象
* @param seedStr 随机种子字符串
* @param keySize 密钥长度, 必须是128 的倍数
* @return
* @throws NoSuchAlgorithmException
*/
private static KeyPair getKeyPair(String seedStr,int keySize) throws NoSuchAlgorithmException {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(keySize,new SecureRandom(seedStr.getBytes()));
return gen.generateKeyPair();
}


/**
* 私钥解密
* @param data
* @param privateKey
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(2, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;

int i = 0;
while (inputLen - offSet > 0) {
byte[] cache;

if (inputLen - offSet > decodePaddingBase) {
cache = cipher.doFinal(data, offSet, decodePaddingBase);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * decodePaddingBase;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}


/**
* 公钥加密
* @param data
* @param publicKey
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicK = keyFactory.generatePublic(x509KeySpec);

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(1, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;

int i = 0;
while (inputLen - offSet > 0) {
byte[] cache;
if (inputLen - offSet > encodePaddingBase) {
cache = cipher.doFinal(data, offSet, encodePaddingBase);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * encodePaddingBase;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}


}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%