使用AI工具写js处理aes加解密
使用AI工具写js处理aes加解密
项目里网络请求数据做了统一的加解密,为了方便,希望在postman里能做相同的加解密流程,整个过程都让AI帮忙自动实现,过程比较曲折,需要不断告诉AI哪里错了,正确的应该是什么
第一版直接在浏览器里运行test.html
的内容
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AES-128 加密与解密演示</title>
</head>
<body>
<h1>AES-128 加密与解密演示</h1>
<label for="inputText">请输入文本:</label>
<textarea id="inputText" rows="4" cols="50">你好,世界!</textarea>
<br><br>
<label for="inputKey">请输入 128 位密钥(16 字节):</label>
<input type="text" id="inputKey" placeholder="请输入 16 个字节的密钥" value="1234567890abcdef">
<br><br>
<button id="encryptButton">加密</button>
<button id="decryptButton">解密</button>
<h2>加密结果:</h2>
<p><strong>加密后的字节流 (Hex):</strong> <span id="encryptedData"></span></p>
<h2>解密结果:</h2>
<p><strong>解密后的数据:</strong> <span id="decryptedData"></span></p>
<script>
// 将字节流转换为 Hex 字符串
function toHexString(byteArray) {
return Array.from(byteArray)
.map(byte => byte.toString(16).padStart(2, '0')) // 每个字节转换为 2 位十六进制
.join('');
}
// 将 Hex 字符串转换为字节流
function hexToBytes(hex) {
const byteArray = [];
for (let i = 0; i < hex.length; i += 2) {
byteArray.push(parseInt(hex.substr(i, 2), 16));
}
return new Uint8Array(byteArray);
}
// AES 加密/解密函数
async function AESCrypt(op, key, data) {
if (!data || data.length === 0) return null;
if (!key || key.length === 0) return null;
const keyLength = 128 / 8; // 128-bit AES => 16 bytes
const iv = new Uint8Array(16); // 使用固定的初始化向量(全0)
const cryptoKey = await crypto.subtle.importKey(
"raw", // AES密钥的类型
key, // 输入的密钥 (Data)
{ name: "AES-CBC" }, // 使用 AES-CBC 模式
false, // 密钥不可导出
op === "encrypt" ? ["encrypt"] : ["decrypt"] // 判断是加密还是解密
);
const algorithm = {
name: "AES-CBC",
iv: iv
};
try {
const result = await crypto.subtle[op](
algorithm, // 算法设置
cryptoKey, // 加密用的密钥
data // 数据
);
return new Uint8Array(result); // 返回加密后的数据
} catch (e) {
console.error(e);
return null;
}
}
// 将字符串转换为字节流
function convertToHex(text) {
const encoder = new TextEncoder(); // 创建 TextEncoder 对象
const byteArray = encoder.encode(text); // 将字符串转换为字节流
return byteArray;
}
// 将字节流转换回字符串
function convertToText(byteArray) {
const decoder = new TextDecoder(); // 创建 TextDecoder 对象
return decoder.decode(byteArray); // 将字节流转换为字符串
}
// 监听加密按钮点击事件
document.getElementById('encryptButton').addEventListener('click', async () => {
const inputText = document.getElementById('inputText').value; // 获取输入的文本
const inputKey = document.getElementById('inputKey').value; // 获取输入的密钥
const key = new TextEncoder().encode(inputKey); // 密钥转换为字节流
const data = convertToHex(inputText); // 字符串转换为字节流
// 执行加密操作
const encryptedData = await AESCrypt("encrypt", key, data);
if (encryptedData) {
// 将加密后的字节流转换为 Hex 字符串
const encryptedHex = toHexString(encryptedData);
// 显示加密结果
document.getElementById('encryptedData').textContent = encryptedHex;
} else {
alert("加密失败!");
}
});
// 监听解密按钮点击事件
document.getElementById('decryptButton').addEventListener('click', async () => {
const encryptedText = document.getElementById('inputText').value;
const inputKey = document.getElementById('inputKey').value;
if (!encryptedText) {
alert("没有加密数据可解密!");
return;
}
const key = new TextEncoder().encode(inputKey); // 密钥转换为字节流
const encryptedData = hexToBytes(encryptedText); // Hex 转回字节数组
// 执行解密操作
const decryptedData = await AESCrypt("decrypt", key, encryptedData);
if (decryptedData) {
const decryptedText = convertToText(decryptedData); // 解密后的文本
// 显示解密结果
document.getElementById('decryptedData').textContent = decryptedText;
} else {
alert("解密失败!");
}
});
</script>
</body>
</html>
第二版直接在node
环境里运行的test_node_aes.js
内容
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
const crypto = require('crypto');
// 将字符串转换为字节流(Buffer)
function textToBuffer(text) {
return Buffer.from(text, 'utf8');
}
// 将字节流转换为字符串
function bufferToText(buffer) {
return buffer.toString('utf8');
}
// 将字节流转换为 Hex 字符串
function bufferToHex(buffer) {
return buffer.toString('hex');
}
// 将 Hex 字符串转换为字节流
function hexToBuffer(hex) {
return Buffer.from(hex, 'hex');
}
// AES 加密函数
function aesEncrypt(text, key) {
// 密钥必须是 16 字节(128 位)
if (key.length !== 16) {
throw new Error("密钥必须为 16 字节");
}
const iv = Buffer.alloc(16, 0); // 使用固定的初始化向量(全0)
const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
// AES 解密函数
function aesDecrypt(encryptedText, key) {
// 密钥必须是 16 字节(128 位)
if (key.length !== 16) {
throw new Error("密钥必须为 16 字节");
}
const iv = Buffer.alloc(16, 0); // 使用固定的初始化向量(全0)
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// 示例用法
const text = "123456";
const enKey = "1234567890abcdef"
const key = Buffer.from(enKey); // 128 位密钥
console.log("原始文本:", text);
console.log("加解密的key:", enKey);
// 加密过程
const encryptedText = aesEncrypt(text, key);
console.log("加密后的 Hex 字符串:", encryptedText);
// 解密过程
const decryptedText = aesDecrypt(encryptedText, key);
console.log("解密后的文本:", decryptedText);
执行的demo
1
2
3
4
node test_node_aes.js
// 原始文本: 你好,世界!
// 加密后的 Hex 字符串: c983fe7879da90299f7bde04f54d63fc3a01d46abaaeac8b01a09f2bc54d242b
// 解密后的文本: 你好,世界!
第三版,在postman
里实现
在postman里加密
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
// 引入 CryptoJS 库(Postman 内置支持)
const CryptoJS = require('crypto-js');
// 原始文本和密钥
const text = "123456"; // 明文
const key = "1234567890abcdef"; // 128 位密钥(16 字节)
const iv = CryptoJS.enc.Utf8.parse('0000000000000000'); // 16 字节初始化向量(对于 ECB 模式,IV 实际上不会使用)
// 使用 AES-128-ECB 模式进行加密
const encrypted = CryptoJS.AES.encrypt(text, CryptoJS.enc.Utf8.parse(key), {
mode: CryptoJS.mode.ECB, // 使用 ECB 模式
padding: CryptoJS.pad.Pkcs7 // 使用 PKCS7 填充
});
// 将加密结果转换为字节流,并转为 Hex 格式字符串
const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
console.log("原始值: " + text); // 原始值: 你好,世界!
console.log("加密key: " + key); // 加密key: 1234567890abcdef
console.log("加密后的值: " + encryptedHex); // 加密后的值: e67a63b9f434013d119040dee91727b3
// 获取动态值 (例如从环境变量、集合变量或生成随机数等)
let token = pm.environment.get('access_token');
// 设置请求头
pm.request.headers.add({
key: 'Authorization',
value: 'Bearer ' + token
});
// 设置其他的key
pm.request.headers.add({
key: 'test',
value: encryptedHex
});
postman里解密
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
// 引入 CryptoJS 库(Postman 内置支持)
const CryptoJS = require('crypto-js');
// 加密后的 Hex 格式密文(例如从环境变量获取)
const encryptedHex = "e67a63b9f434013d119040dee91727b3"; // 示例加密结果
const key = "1234567890abcdef"; // 16 字节密钥
// 将 Hex 格式的密文转换为 CryptoJS 的 WordArray 类型
const encryptedData = CryptoJS.enc.Hex.parse(encryptedHex);
// 解密
const decrypted = CryptoJS.AES.decrypt(
{ ciphertext: encryptedData },
CryptoJS.enc.Utf8.parse(key),
{
mode: CryptoJS.mode.ECB, // 使用相同的 ECB 模式
padding: CryptoJS.pad.Pkcs7 // 使用相同的 PKCS7 填充
}
);
// 解密后的字节流,转换为 UTF-8 字符串
const decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
// 打印解密结果
console.log("原始值:", encryptedHex); // 原始值: e67a63b9f434013d119040dee91727b3
console.log("key:", key); // key: 1234567890abcdef
console.log("解密后的值:", decryptedText); // 解密后的值: 你好,世界!
pm.environment.set("decryptedText", decryptedText);
原始的swift的写法
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
class Test {
static func AESCrypt(op: CCOperation, key: Data?, data: Data?) -> Data? {
guard let data = data, data.count > 0 else { return nil }
guard let key = key, key.count > 0 else { return nil }
let keyLength = kCCKeySizeAES128
let cryptLength = data.count + kCCBlockSizeAES128
var cryptData = Data(count: cryptLength)
var numBytesEncrypted: Int = 0
let cryptStatus = cryptData.withUnsafeMutableBytes { cryptBytes in
data.withUnsafeBytes { dataBytes in
key.withUnsafeBytes { keyBytes in
CCCrypt(op,
CCAlgorithm(kCCAlgorithmAES),
CCOptions(kCCOptionECBMode + kCCOptionPKCS7Padding),
keyBytes.baseAddress, keyLength,
nil,
dataBytes.baseAddress, data.count,
cryptBytes.baseAddress, cryptLength,
&numBytesEncrypted)
}
}
}
if cryptStatus == kCCSuccess {
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)
return cryptData
}
return nil
}
static func test() {
let text = "123456"
let key = "1234567890abcdef"
if let textData = text.data(using: .utf8),
let deData = AESCrypt(op: CCOperation(kCCEncrypt), key: key.data(using: .utf8), data: textData) {
let deText = deData.toHexString()
print("原始值:\(text)")
print("key:\(key)")
print("加密后的值:\(deText)")
// 解密
let data2 = Data(hex: deText)
if let enData = AESCrypt(op: CCOperation(kCCDecrypt), key: key.data(using: .utf8), data: data2),
let text2 = String(data: enData, encoding: .utf8) {
print("解密后的值: \(text2)")
}
}
}
// 原始值:123456
// key:1234567890abcdef
// 加密后的值:E67A63B9F434013D119040DEE91727B3
// 解密后的值: 123456
}
extension Data {
public init(hex: String) {
self.init(Array<UInt8>(hex: hex))
}
public var bytes: Array<UInt8> {
return Array(self)
}
public func toHexString() -> String {
return bytes.toHexString()
}
}
This post is licensed under CC BY 4.0 by the author.