Java RSA 非对称加密算法工具类和 Jwt Toekn 工具类

这里提供一个 RSA 加密算法的工具类,其中包含生成密钥、加密、解密、加签、验签等 RSA 常用的方法,可以直接使用

引入 Maven 依赖,(如果不引入则需要修改 base64 加密、解密方法为 java.ultils.base64)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
package cn.likfees.common.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;


/**
* @Description RSA非对称加密算法工具类
* @Author Likfees
* @Date 2022/07/04 20:26
*/
public class RSAUtils {


/**
* RSA最大加密明文大小 2048/8-11
*/
private static final int MAX_ENCRYPT_BLOCK = 245;

/**
* RSA最大解密密文大小 2048/8
*/
private static final int MAX_DECRYPT_BLOCK = 256;
/**
* 定义加密方式
*/
public static final String KEY_RSA = "RSA";
/**
* 定义公钥
*/
public static final String KEY_RSA_PUBLICKEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhbMJG9i6O0T1hQ8oCoThMAg/0mlcerjYn+wMdZudoDCeEbxKYebs+WoNvBmV26A/co9yJ2+aUIf60kkJ6YwDh9pXSk2vgm7x0TAZ9HzRhpk6td4JO4HM9QpPaQG2Z3Tw8DnhNk7yGADp+weLqgULDDlUI7lm1s1G9OSY+ZK2TwjKPSC4j1CnjD6kvSW1qVGB0GhkreX877Rop+KbOmVE+JtQQgc+DcOgyMjGtSvDGrwBsI569wrywlOeFMLqVDlVLi3ugWDSEn3EHz63Nj442VSfR6ukxtifIwmogUI4VplXQoO4Am6kKH50tkggqVBNFGh0s5qavpig0XYkn42+6QIDAQAB";
/**
* 定义私钥
*/
public static final String KEY_RSA_PRIVATEKEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCFswkb2Lo7RPWFDygKhOEwCD/SaVx6uNif7Ax1m52gMJ4RvEph5uz5ag28GZXboD9yj3Inb5pQh/rSSQnpjAOH2ldKTa+CbvHRMBn0fNGGmTq13gk7gcz1Ck9pAbZndPDwOeE2TvIYAOn7B4uqBQsMOVQjuWbWzUb05Jj5krZPCMo9ILiPUKeMPqS9JbWpUYHQaGSt5fzvtGin4ps6ZUT4m1BCBz4Nw6DIyMa1K8MavAGwjnr3CvLCU54UwupUOVUuLe6BYNISfcQfPrc2PjjZVJ9Hq6TG2J8jCaiBQjhWmVdCg7gCbqQofnS2SCCpUE0UaHSzmpq+mKDRdiSfjb7pAgMBAAECggEAR3vSAvF9oPLd0qan4ffp7qR6eyWaLINoTxkGEFuDi4JzAUiK/I1bZn8tmMSVOzgStE292xfwid4qXQRwKE6UFK7IvRGMJVDsOcxeFDooTK7glRyCEy7zRpCcpKglvmrn54kKwN600eCrOWxvYBgSMBb2xaL7OR3IMmeG4uluUBK8u8phRfXbt1CaQvzfqZqZbspE/XX23Lgnxq/7PV2ME1ukOHAzQm8XdSQosLTX2WhbGBCG8xG1Ia9qZ5R63Y3Gk8gnXxVEpzcbtF7sxU/hDwdpfb7wiIQTyoBcL/XIr9I42p4TvizAtr4spzzkIMprKiEAP1IozBCD3YWvPMUJgQKBgQDGgSoosujtJ2OicvtJrO67YW6ecMc9L2VBY/qAxrivC+Ups/rS2PPchNy9abv8JGnCpa1MdOUudpaSv9g47BES5NwZ38bGHj+U7Wg9VIRQ/G8dxWelQrVgALLJ9mjDmJrenUmfwBaYqej3fvYZMA/hWT0CUhBWKVn1X0nPzXlYRwKBgQCsbKgHrQK39bccVMBDBnsRLXzJOLcIFu+AHShhqQfttMeDOQiXuVpy4CAv84y0Y3/rV7Yr6RGZ1pOTOr2NvTGUka/ZfOvYi8UPULzAOLh02KBb1LtcRrvwPYuoLxKN81XYZ85yS7EggpEFtbsm0YSZozv4Vx5uccHxevzHXBn3TwKBgQCj83DPtp09qufW96LnAicXquyDfmCA/5FhBeOT0w4cvfVjkVycI0afHzl2VEtIgQa9Frvgxze3PYk14bADq66abV4BHNt/LOKU7dTHuvOiNCzOaQom68cEaO9CcfureXKIZV62zB+drdBWAo3e1dx34o3KSd9mWrcLO82qDWqo5wKBgGxZAuV/5Dtw3hWhdAcqJV9P9CAF0Y31y533tI5Zxy+p780Xo7yjrqCNEezP4FTiSVm7ji/djz/aRHW57a8JegRf396Mzy8N9VCAbXtkqRRTo8DQ1sNPd32pTv7qRYCJriIEaQgNZEqHgVXTMr1b3zUkC+Ur6WWBeluh6wHjcDWlAoGAfduQDd31wN1r8MaTv0Uj1k4YXWPQdfKlmATsD0iT1oMg2bfPVwPhs+UI5hwhu2KD/zjzS7qGyfXiTXLh11pJrlFV9D5OVsxwOKwCGe1mUuwmBtWTTLxw1Irlz91Tu3sgioSZ9MeuUHI1psAttcnxGmOq6taEXCFkr20q+9SH3fk=";
/**
* 定义签名算法
*/
private final static String KEY_RSA_SIGNATURE = "sha256withRSA";

/**
* 生成公私密钥对
*/
public static Map<String, Object> init() {
Map<String, Object> map = null;
try {
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
//设置密钥对的bit数,越大越安全,但速度减慢,一般使用512或1024、2048
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
// 获取公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 获取私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 将密钥对封装为Map
map = new HashMap<String, Object>(2);
map.put(KEY_RSA_PUBLICKEY, publicKey);
map.put(KEY_RSA_PRIVATEKEY, privateKey);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

return map;
}

/**
* 获取 RSAPublicKey
*/
public static RSAPublicKey getPublicKey() throws Exception {
byte[] decoded = Base64.decodeBase64(KEY_RSA_PUBLICKEY);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PublicKey publicKey = factory.generatePublic(new X509EncodedKeySpec(decoded));
return (RSAPublicKey) publicKey;
}

/**
* 获取 RSAPrivateKey
*/
public static RSAPrivateKey getPrivateKey() throws Exception {
byte[] decoded = Base64.decodeBase64(KEY_RSA_PRIVATEKEY);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PrivateKey privateKey = factory.generatePrivate(new PKCS8EncodedKeySpec(decoded));
return (RSAPrivateKey) privateKey;
}


/**
* 公钥加密 如果大于245则分段加密
*/
public static String encryptByPublic(String encryptingStr, String publicKeyStr) {
try {
// 将公钥由字符串转为UTF-8格式的字节数组
byte[] publicKeyBytes = Base64.decodeBase64(publicKeyStr);
// 获得公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
// 取得待加密数据
byte[] data = encryptingStr.getBytes(StandardCharsets.UTF_8);
KeyFactory factory;
factory = KeyFactory.getInstance(KEY_RSA);
PublicKey publicKey = factory.generatePublic(keySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
// 返回加密后由Base64编码的加密信息
return new String(Base64.encodeBase64(encryptedData));
} catch (Exception e) {
e.printStackTrace();
}

return null;
}

/**
* 私钥解密 如果大于256则分段解密
*/
public static String decryptByPrivate(String encryptedStr, String privateKeyStr) {
try {
// 对私钥解密
byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr);
// 获得私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
// 获得待解密数据
byte[] data = Base64.decodeBase64(encryptedStr);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PrivateKey privateKey = factory.generatePrivate(keySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
// 返回UTF-8编码的解密信息
return new String(decryptedData, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}

return null;
}

/**
* 私钥加密 如果大于245则分段加密
*/
public static String encryptByPrivate(String encryptingStr, String privateKeyStr) {
try {
byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr);
// 获得私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
// 取得待加密数据
byte[] data = encryptingStr.getBytes(StandardCharsets.UTF_8);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PrivateKey privateKey = factory.generatePrivate(keySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
// 返回加密后由Base64编码的加密信息
return new String(Base64.encodeBase64(encryptedData));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* 公钥解密 如果大于256则分段解密
*/
public static String decryptByPublic(String encryptedStr, String publicKeyStr) {
try {
// 对公钥解密
byte[] publicKeyBytes = Base64.decodeBase64(publicKeyStr);
// 取得公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
// 取得待加密数据
byte[] data = Base64.decodeBase64(encryptedStr);
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
PublicKey publicKey = factory.generatePublic(keySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
// 返回UTF-8编码的解密信息
return new String(decryptedData, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* 用私钥对加密数据进行签名
*/
public static String sign(String encryptedStr, String privateKey) {
String str = "";
try {
//将私钥加密数据字符串转换为字节数组
byte[] data = encryptedStr.getBytes();
// 解密由base64编码的私钥
byte[] bytes = Base64.decodeBase64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// 取私钥对象
PrivateKey key = factory.generatePrivate(pkcs);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initSign(key);
signature.update(data);
str = new String(Base64.encodeBase64(signature.sign()));
} catch (Exception e) {
e.printStackTrace();
}
return str;
}

/**
* 校验数字签名
*
* @return 校验成功返回true,失败返回false
*/
public static boolean verify(String encryptedStr, String publicKey, String sign) {
boolean flag = false;
try {
//将私钥加密数据字符串转换为字节数组
byte[] data = encryptedStr.getBytes();
// 解密由base64编码的公钥
byte[] bytes = Base64.decodeBase64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
// 取公钥对象
PublicKey key = factory.generatePublic(keySpec);
// 用公钥验证数字签名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initVerify(key);
signature.update(data);
flag = signature.verify(Base64.decodeBase64(sign));
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}


/**
* 功能描述:格式化公私钥 C++格式
* 公钥字符串开头要加上“-----BEGIN PUBLIC KEY-----\n”,结尾加上“\n-----END PUBLIC KEY-----\n”
* 私钥字符串开头要加上“-----BEGIN RSA PRIVATE KEY-----\n”,结尾加上“\n-----END RSA PRIVATE KEY-----\n”
*
* @param str 要格式的字符串, flag
* @param flag true为公 false为私
* @return java.lang.String
* @date 2020/3/18 16:40
* @version 1.0
*/
public static String formatStr(String str, boolean flag) {
StringBuilder sb = new StringBuilder(str);
for (int i = 0, len = sb.length(); i < len; i++) {
if (i % 64 == 0) {
sb.insert(i, "\n");
}
}
if (flag) {
sb = new StringBuilder("-----BEGIN PUBLIC KEY-----").append(sb).append("\n-----END PUBLIC KEY-----\n");
} else {
sb = new StringBuilder("-----BEGIN RSA PRIVATE KEY-----").append(sb).append("\n-----END RSA PRIVATE KEY-----\n");
}
return sb.toString();
}


/**
* 测试方法
*/
public static void main(String[] args) {
// 生成 RSA 密钥
Map<String, Object> map = new HashMap<String, Object>(2);
map = RSAUtils.init();
System.out.println(map);


// 使用密钥进行认证
String publicKey = RSAUtils.KEY_RSA_PUBLICKEY;
String privateKey = RSAUtils.KEY_RSA_PRIVATEKEY;
System.out.println("publicKey = " + publicKey);
System.out.println("privateKey = " + privateKey);
System.out.println("formatStr(publicKey,false) = " + formatStr(publicKey, true));
System.out.println("formatStr(privateKey,false) = " + formatStr(privateKey, false));
//由前四行代码获得公、私密钥
// publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjVgHojy7oZ1Gl/iT9CXgvzlqPyV5wxvSRW7f6qDQh1FreYVTIbyVOees9LDbyFyocLCx6Cz3E4csHJvjwIem6SuZpIpmeJGS5bo04JVK2JwdqbFoIXd1Q5bGsA17nUNlnSR4h3ODM8OCKsC0Qpt1KSvN0WB2JUGBbUFwiPxrwEMLeYntz4cABBA/KYt5Ac9HBk5TDRDpFVlOM43t0B2219GxQOxm1x8fFjwzKV06nwYbmIuqoKqQVlym3FYrYiOdd0/iXXxp4Whi0Hdo7XyfaQhoCCd3FNnFP8Ng0HDAW99HxEaP9eIuC4wCV16o8jsUzm7V/yhTF1NlIPlTQW35hQIDAQAB";
String str = "1 InnoDB 支持表锁和行锁,使用索引作为检索条件修改数据时采用行锁,否则采用表锁。\n" + "2 InnoDB 自动给修改操作加锁,给查询操作不自动加锁" + "3 行锁可能因为未使用索引而升级为表锁,所以除了检查索引是否创建的同时,也需要通过explain执行计划查询索引是否被实际使用。, RSA!";
// 公钥加密,私钥解密
String enStr1 = RSAUtils.encryptByPublic(str, publicKey);
System.out.println("公钥加密后:" + enStr1);
String deStr1 = RSAUtils.decryptByPrivate(enStr1, privateKey);
System.out.println("私钥解密后:" + deStr1);
// 私钥加密,公钥解密
String enStr2 = RSAUtils.encryptByPrivate(str, privateKey);
System.out.println("私钥加密后:" + enStr2);
String deStr2 = RSAUtils.decryptByPublic(enStr2, publicKey);
System.out.println("公钥解密后:" + deStr2);
// 产生签名
String sign = sign(enStr2, privateKey);
System.out.println("签名:" + sign);
// 验证签名
boolean status = verify(enStr2, publicKey, sign);
System.out.println("状态:" + status);
}
}

RSA 工具类 2

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
package com.imooc.bilibili.service.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


/**
* RSA加密
* 非对称加密,有公钥和私钥之分,公钥用于数据加密,私钥用于数据解密。加密结果可逆
* 公钥一般提供给外部进行使用,私钥需要放置在服务器端保证安全性。
* 特点:加密安全性很高,但是加密速度较慢
*
*/
public class RSAUtil {

private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQk33iNdA8Iey7J6XrBsidqn6u8EDLWPHsfEUgLQ3qiTikhPKDTzZkpAfU/O0x6NvSKa7Dp0+uqWT3vnW1De0+3u8mCYdVfOdH94VG4xg5U5UrRJei8HhPiXuvKQ+6NBtebCCW5adZ4pBgOiU14cJLhVmm+dYiLo3IDD5LqrlomQIDAQAB";

private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJCTfeI10Dwh7LsnpesGyJ2qfq7wQMtY8ex8RSAtDeqJOKSE8oNPNmSkB9T87THo29IprsOnT66pZPe+dbUN7T7e7yYJh1V850f3hUbjGDlTlStEl6LweE+Je68pD7o0G15sIJblp1nikGA6JTXhwkuFWab51iIujcgMPkuquWiZAgMBAAECgYA1UT9mciQWWQh9yNRmhXzssFjB2TZ8B5RIe1fe0t7D9NEf0yvAgzDzEo8U3CX5dv/CVL7vxr8bEbt7phCwsa8hJiLEOr7hLZaJzXVTbvfqb91oCZGNkqDQ3NJfGBMVgUmltEYF2Bbk3U0NDyat+Gu54tRd2OH+adJYKsD0XYeDBQJBAN5FE8E04A4FA1q8mQbVTSVJDYIEJwOrdC0r3iZ7za5CyXGk+br8pFalRePFaksRGdN32+mYhDKVNrNHspAObVMCQQCmhBsD+xiWrmpnrzeIfCW1cX8qRC3/RMkq0ACw3l6YedNFdN2Tb5WsRHmcbCI9y8mfLHiG/X1R+zHZKG67EKjjAkAmvAkGSY2mQ89i160fWLq5/bIh71FRPWbgnF15fWfJr4/lgyeWI4MMKn80g2nTrSZACQpE+jRHkGNY+OywWCNLAkEAli5nvztkfeJpDYK2b16pE/B9ZL2BTs3XMcnQFbU5VAPsTKSOgz8MmwZXOIE+kMWP3wPY4McXlC0eVGFnHUh1SQJAeAl3RPk+XbZDMYfPkStRJwocG9Ap+88mwTgR1I7uPzZ1aM84/WsQskiVMXv2SZLmMWvYtnhIKosL6IACp2AcDA==";

public static void main(String[] args) throws Exception{
String str = RSAUtil.encrypt("123456");
System.out.println(str);
}

public static String getPublicKeyStr(){
return PUBLIC_KEY;
}

public static RSAPublicKey getPublicKey() throws Exception {
byte[] decoded = Base64.decodeBase64(PUBLIC_KEY);
return (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decoded));
}

public static RSAPrivateKey getPrivateKey() throws Exception {
byte[] decoded = Base64.decodeBase64(PRIVATE_KEY);
return (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
}

public static RSAKey generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024, new SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
String privateKeyString = new String(Base64.encodeBase64(privateKey.getEncoded()));
return new RSAKey(privateKey, privateKeyString, publicKey, publicKeyString);
}

public static String encrypt(String source) throws Exception {
byte[] decoded = Base64.decodeBase64(PUBLIC_KEY);
RSAPublicKey rsaPublicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(1, rsaPublicKey);
return Base64.encodeBase64String(cipher.doFinal(source.getBytes(StandardCharsets.UTF_8)));
}

public static Cipher getCipher() throws Exception {
byte[] decoded = Base64.decodeBase64(PRIVATE_KEY);
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(2, rsaPrivateKey);
return cipher;
}

public static String decrypt(String text) throws Exception {
Cipher cipher = getCipher();
byte[] inputByte = Base64.decodeBase64(text.getBytes(StandardCharsets.UTF_8));
return new String(cipher.doFinal(inputByte));
}

public static class RSAKey {
private RSAPrivateKey privateKey;
private String privateKeyString;
private RSAPublicKey publicKey;
public String publicKeyString;

public RSAKey(RSAPrivateKey privateKey, String privateKeyString, RSAPublicKey publicKey, String publicKeyString) {
this.privateKey = privateKey;
this.privateKeyString = privateKeyString;
this.publicKey = publicKey;
this.publicKeyString = publicKeyString;
}

public RSAPrivateKey getPrivateKey() {
return this.privateKey;
}

public void setPrivateKey(RSAPrivateKey privateKey) {
this.privateKey = privateKey;
}

public String getPrivateKeyString() {
return this.privateKeyString;
}

public void setPrivateKeyString(String privateKeyString) {
this.privateKeyString = privateKeyString;
}

public RSAPublicKey getPublicKey() {
return this.publicKey;
}

public void setPublicKey(RSAPublicKey publicKey) {
this.publicKey = publicKey;
}

public String getPublicKeyString() {
return this.publicKeyString;
}

public void setPublicKeyString(String publicKeyString) {
this.publicKeyString = publicKeyString;
}
}
}

JWT 工具类

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
package cn.likfees.common.utils;

import cn.likfees.entity.exception.ConditionException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

@Slf4j
public class TokenUtils {

private static final String ISSUER = "fungs.cn";
private static final Integer EXPIRE =30 ;

/**
* 生成token
*
* @param userId
* @return
* @throws Exception
*/
public static String generateToken(Long userId, String phone, String avatar, String nickname) {
Algorithm algorithm = null;
try {
algorithm = Algorithm.RSA256(RSAUtils.getPublicKey(), RSAUtils.getPrivateKey());
} catch (Exception e) {
throw new RuntimeException(e);
}
Calendar calendar = Calendar.getInstance(); // 日历类用于生成过期时间
calendar.setTime(new Date());
calendar.add(Calendar.SECOND, EXPIRE);
return JWT.create().withKeyId(String.valueOf(userId)).withIssuer(ISSUER).withExpiresAt(calendar.getTime()).withClaim("user_id", userId).withClaim("phone", phone).withClaim("avatar", avatar).withClaim("nickname", nickname).sign(algorithm);
}

public static Map<String, Claim> VerifyToken(String token) {
try {
Algorithm algorithm = Algorithm.RSA256(RSAUtils.getPublicKey(), RSAUtils.getPrivateKey());
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
Map<String, Claim> claims = jwt.getClaims();
return claims;
} catch (TokenExpiredException e) {
throw new ConditionException(401, "token 令牌已过期");
} catch (SignatureVerificationException e) {
e.printStackTrace();
log.info(token);
throw new ConditionException(401, "token 令牌无效");
} catch (Exception e) {
throw new RuntimeException(e);
}

}

}