微信小程序使用aes加密

微信小程序使用 aes 加密

提供两种库的实现方式。

使用 crypto-js 实现

注:只能使用 3.x 版本, 4.x 版本不支持微信小程序。

小程序构建后依赖体积大约为 218kb

1
2
3
4
5
6
7
8
9
const message = CryptoJS.enc.Utf8.parse(data);
const key = CryptoJS.enc.Utf8.parse(encryptKey);
const iv = CryptoJS.enc.Utf8.parse(encryptIV);
const cryptoStr = CryptoJS.AES.encrypt(message, key, {
iv,
});
// 以下分别是以base64以及hex格式输出
const base64Str = CryptoJS.format.OpenSSL.stringify(cryptoStr); // 或者直接 cryptoStr.toString()
const hexStr = CryptoJS.format.Hex.stringify(cryptoStr);

使用 aes-js 实现

小程序构建后依赖体积大约为 64kb

1
2
3
4
5
6
7
8
const message = aesjs.padding.pkcs7.pad(aesjs.utils.utf8.toBytes(data));
const key = aesjs.utils.utf8.toBytes(encryptKey);
const iv = aesjs.utils.utf8.toBytes(encryptIV);
const aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
const encryptedBytes = aesCbc.encrypt(message);
// 以下分别是以base64以及hex格式输出
const hexStr = aesjs.utils.hex.fromBytes(encryptedBytes);
const base64Str = arrayBufferToBase64(encryptedBytes);

aes-js 自带的工具函数只支持输出 hex 格式,若需要输出 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
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
exports.weBtoa = function (string) {
string = String(string);
var bitmap,
a,
b,
c,
result = "",
i = 0,
rest = string.length % 3;
for (; i < string.length; ) {
if (
(a = string.charCodeAt(i++)) > 255 ||
(b = string.charCodeAt(i++)) > 255 ||
(c = string.charCodeAt(i++)) > 255
)
throw new TypeError(
"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."
);
bitmap = (a << 16) | (b << 8) | c;
result +=
b64.charAt((bitmap >> 18) & 63) +
b64.charAt((bitmap >> 12) & 63) +
b64.charAt((bitmap >> 6) & 63) +
b64.charAt(bitmap & 63);
}
return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
};
function arrayBufferToBase64(bytes) {
let binary = "";
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return weBtoa(binary);
}

补充:小程序加解密工具函数

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
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var b64re =
/^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
exports.weBtoa = function (string) {
string = String(string);
var bitmap,
a,
b,
c,
result = "",
i = 0,
rest = string.length % 3;
for (; i < string.length; ) {
if (
(a = string.charCodeAt(i++)) > 255 ||
(b = string.charCodeAt(i++)) > 255 ||
(c = string.charCodeAt(i++)) > 255
)
throw new TypeError(
"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."
);
bitmap = (a << 16) | (b << 8) | c;
result +=
b64.charAt((bitmap >> 18) & 63) +
b64.charAt((bitmap >> 12) & 63) +
b64.charAt((bitmap >> 6) & 63) +
b64.charAt(bitmap & 63);
}
return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
};
exports.weAtob = function (string) {
string = String(string).replace(/[\t\n\f\r ]+/g, "");
if (!b64re.test(string))
throw new TypeError(
"Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."
);
string += "==".slice(2 - (string.length & 3));
var bitmap,
result = "",
r1,
r2,
i = 0;
for (; i < string.length; ) {
bitmap =
(b64.indexOf(string.charAt(i++)) << 18) |
(b64.indexOf(string.charAt(i++)) << 12) |
((r1 = b64.indexOf(string.charAt(i++))) << 6) |
(r2 = b64.indexOf(string.charAt(i++)));
result +=
r1 === 64
? String.fromCharCode((bitmap >> 16) & 255)
: r2 === 64
? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
: String.fromCharCode(
(bitmap >> 16) & 255,
(bitmap >> 8) & 255,
bitmap & 255
);
}
return result;
};
function b64DecodeUnicode(str) {
return decodeURIComponent(
exports.weAtob(str).replace(/(.)/g, function (p) {
var code = p.charCodeAt(0).toString(16).toUpperCase();
if (code.length < 2) {
code = "0" + code;
}
return "%" + code;
})
);
}
function base64_url_decode(str) {
var output = str.replace(/-/g, "+").replace(/_/g, "/");
switch (output.length % 4) {
case 0:
break;
case 2:
output += "==";
break;
case 3:
output += "=";
break;
default:
throw "Illegal base64url string!";
}
try {
return b64DecodeUnicode(output);
} catch (err) {
return exports.weAtob(output);
}
}
function weappJwtDecode(token, options) {
if (typeof token !== "string") {
throw "Invalid token specified";
}
options = options || {};
var pos = options.header === true ? 0 : 1;
try {
return JSON.parse(base64_url_decode(token.split(".")[pos]));
} catch (e) {
throw "Invalid token specified: " + e.message;
}
}
exports.default = weappJwtDecode;

微信小程序使用aes加密
https://www.wobushi.top/2023/微信小程序使用aes加密/
作者
Pride Su
发布于
2023年2月15日
许可协议