Java 和 js 互加解密(1) — AES对称加密算法

本文整理了 Java 和 js 关于AES算法的互加解密,方便开发使用。部分代码来源于网络。

js 前台加密数据,Java 后台解密数据。

Java 和 js 互加解密 — AES对称加密

Java 和 js 互加解密 — AES对称加密

AES算法简介

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

更多信息请查阅维基词条:高级加密标准

Java实现AES加解密

该工具类基于 jdk1.8 进行封装,如果你的 jdk 低于1.8,部分代码可能需要做一定的调整(如Base64编码解码)
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
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
* AES加解密的工具类
*
* @author hxulin
*/
public final class AESUtils {

/**
* 字符编码
*/
private static final String CHARACTER_ENCODING = "utf-8";

/**
* 生成密钥的基本字符
*/
private static final String BASE_CHARACTER = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

private AESUtils() {

}

/**
* 生成随机密钥
*
* @return 随机密钥
*/
public static String initKey() {
return generateKeyOrIV();
}

/**
* 生成初始向量
*
* @return 初始向量
*/
public static String initIV() {
return generateKeyOrIV();
}

/**
* 生成随机密钥、初始向量
*/
private static String generateKeyOrIV() {
StringBuilder sBuilder = new StringBuilder();
double r;
for (int i = 0; i < 16; i++) {
r = Math.random() * BASE_CHARACTER.length();
sBuilder.append(BASE_CHARACTER.charAt((int) r));
}
return sBuilder.toString();
}

/**
* 使用AES算法加密字符串
*
* @param data 需要加密的原文
* @param key 密钥(16位字母、数字或符号)
* @param iv 初始向量(16位字母、数字或符号),使用CBC模式,需要一个向量iv,可增加加密算法的强度
* @return 加密后进行Base64的密文
* @throws Exception 加密失败
*/
public static String encrypt(String data, String key, String iv) throws Exception {
return Base64.getEncoder().encodeToString(encrypt(data.getBytes(CHARACTER_ENCODING), key, iv));
}

/**
* 使用AES算法加密数据
*
* @param data 需要加密的数据
* @param key 密钥(16位字母、数字或符号)
* @param iv 初始向量(16位字母、数字或符号),使用CBC模式,需要一个向量iv,可增加加密算法的强度
* @return 加密后的数据
* @throws Exception 加密失败
*/
public static byte[] encrypt(byte[] data, String key, String iv) throws Exception {
return crypto(Cipher.ENCRYPT_MODE, data, key, iv);
}

/**
* 使用AES算法解密字符串
*
* @param data 需要解密的密文
* @param key 密钥(16位字母、数字或符号)
* @param iv 初始向量(16位字母、数字或符号)
* @return 解密后的明文
* @throws Exception 解密失败
*/
public static String decrypt(String data, String key, String iv) throws Exception {
byte[] decrypted = decrypt(Base64.getDecoder().decode(data), key, iv);
return new String(decrypted, CHARACTER_ENCODING);
}

/**
* 使用AES算法解密数据
*
* @param data 需要解密的数据
* @param key 密钥(16位字母、数字或符号)
* @param iv 初始向量(16位字母、数字或符号)
* @return 解密后的数据
* @throws Exception 解密失败
*/
public static byte[] decrypt(byte[] data, String key, String iv) throws Exception {
return crypto(Cipher.DECRYPT_MODE, data, key, iv);
}

/**
* 加解密数据
*/
private static byte[] crypto(int opmode, byte[] content, String key, String iv) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(CHARACTER_ENCODING), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 算法/模式/补码方式
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(CHARACTER_ENCODING));
cipher.init(opmode, keySpec, ivParameterSpec);
return cipher.doFinal(content);
}

}

使用样例:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void test() throws Exception {
String key = AESUtils.initKey();
System.out.println("生成密钥:" + key);
String iv = AESUtils.initIV();
System.out.println("生成初始向量:" + iv);
String content = "你好师姐"; // 待加密内容
String encrypt = AESUtils.encrypt(content, key, iv);
System.out.println("明文内容:"+ content);
System.out.println("加密结果:"+ encrypt);
System.out.println("解密结果:"+ AESUtils.decrypt(encrypt, key, iv));
}

运行结果:

生成密钥:grXBjElVVSJd4QSq
生成初始向量:DmuZulkW1x240brw
明文内容:你好师姐
加密结果:BqbUwVOXJMwwtB4CquWsLA==
解密结果:你好师姐

js实现AES加解密

前端 js 实现AES加解密,依赖第三方库:CryptoJS
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
/**
* AES加密
*
* @param content 待加密的内容
* @param secretKey 密钥
* @param iv 初始向量
* @returns {string} 加密结果
*/
function aesEncrypt(content, secretKey, iv) {
return CryptoJS.AES.encrypt(content, CryptoJS.enc.Utf8.parse(secretKey), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
}

/**
* AES解密
*
* @param content 待解密的内容
* @param secretKey 密钥
* @param iv 初始向量
* @returns {string} 解密结果
*/
function aesDecrypt(content, secretKey, iv) {
return CryptoJS.AES.decrypt(content, CryptoJS.enc.Utf8.parse(secretKey), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
}

完整项目地址:https://github.com/hxulin/encryption

(完)