@ivujs/i-utils 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -42
- package/dist/cjs/ID-card/index.cjs +21 -13
- package/dist/cjs/array/index.cjs +40 -34
- package/dist/cjs/clipboard/index.cjs +14 -10
- package/dist/cjs/color/index.cjs +73 -59
- package/dist/cjs/cookie/index.cjs +16 -13
- package/dist/cjs/crypto/base64/base64.cjs +398 -206
- package/dist/cjs/crypto/base64/index.cjs +58 -35
- package/dist/cjs/crypto/md5/index.cjs +33 -8
- package/dist/cjs/crypto/md5/md5.cjs +298 -844
- package/dist/cjs/crypto/sha256/index.cjs +95 -0
- package/dist/cjs/crypto/sha256/sha256.cjs +557 -0
- package/dist/cjs/crypto/sm3/index.cjs +27 -0
- package/dist/cjs/crypto/sm3/sm3.cjs +200 -0
- package/dist/cjs/crypto/sm4/index.cjs +101 -0
- package/dist/cjs/crypto/sm4/sm4.cjs +498 -0
- package/dist/cjs/date/index.cjs +379 -335
- package/dist/cjs/desensitized/index.cjs +21 -18
- package/dist/cjs/device/index.cjs +33 -30
- package/dist/cjs/dom/index.cjs +26 -23
- package/dist/cjs/file/index.cjs +51 -41
- package/dist/cjs/function/index.cjs +22 -19
- package/dist/cjs/id/index.cjs +6 -2
- package/dist/cjs/index.cjs +108 -127
- package/dist/cjs/keycode/index.cjs +9 -12
- package/dist/cjs/math/index.cjs +113 -81
- package/dist/cjs/number/index.cjs +10 -7
- package/dist/cjs/object/index.cjs +77 -30
- package/dist/cjs/pagination/index.cjs +25 -10
- package/dist/cjs/random/index.cjs +8 -5
- package/dist/cjs/regexp/index.cjs +23 -20
- package/dist/cjs/storage/index.cjs +4 -1
- package/dist/cjs/storage/localStorage.cjs +5 -5
- package/dist/cjs/storage/sessionStorage.cjs +6 -6
- package/dist/cjs/string/index.cjs +66 -63
- package/dist/cjs/url/index.cjs +83 -80
- package/dist/cjs/validate/index.cjs +122 -106
- package/dist/es/ID-card/index.d.ts +19 -14
- package/dist/es/ID-card/index.mjs +22 -14
- package/dist/es/array/index.d.ts +56 -50
- package/dist/es/array/index.mjs +40 -34
- package/dist/es/clipboard/index.d.ts +10 -7
- package/dist/es/clipboard/index.mjs +14 -10
- package/dist/es/color/index.d.ts +28 -25
- package/dist/es/color/index.mjs +73 -59
- package/dist/es/constants/date.d.ts +4 -174
- package/dist/es/constants/id-card.d.ts +4 -43
- package/dist/es/constants/index.d.ts +11 -7
- package/dist/es/constants/keycode.d.ts +1 -103
- package/dist/es/constants/lang.d.ts +4 -4
- package/dist/es/constants/math.d.ts +4 -4
- package/dist/es/constants/regexp.d.ts +4 -24
- package/dist/es/constants/sort.d.ts +4 -5
- package/dist/es/cookie/index.d.ts +13 -13
- package/dist/es/cookie/index.mjs +16 -13
- package/dist/es/crypto/base64/base64.d.ts +8 -5
- package/dist/es/crypto/base64/base64.mjs +393 -204
- package/dist/es/crypto/base64/index.d.ts +41 -24
- package/dist/es/crypto/base64/index.mjs +53 -32
- package/dist/es/crypto/index.d.ts +8 -8
- package/dist/es/crypto/md5/index.d.ts +20 -7
- package/dist/es/crypto/md5/index.mjs +32 -9
- package/dist/es/crypto/md5/md5.d.ts +9 -142
- package/dist/es/crypto/md5/md5.mjs +299 -844
- package/dist/es/crypto/sha256/index.d.ts +52 -0
- package/dist/es/crypto/sha256/index.mjs +86 -0
- package/dist/es/crypto/sha256/sha256.d.ts +82 -0
- package/dist/es/crypto/sha256/sha256.mjs +548 -0
- package/dist/es/crypto/sm3/index.d.ts +13 -0
- package/dist/es/crypto/sm3/index.mjs +24 -0
- package/dist/es/crypto/sm3/sm3.d.ts +3 -0
- package/dist/es/crypto/sm3/sm3.mjs +197 -0
- package/dist/es/crypto/sm4/index.d.ts +56 -0
- package/dist/es/crypto/sm4/index.mjs +95 -0
- package/dist/es/crypto/sm4/sm4.d.ts +48 -0
- package/dist/es/crypto/sm4/sm4.mjs +490 -0
- package/dist/es/date/index.d.ts +236 -175
- package/dist/es/date/index.mjs +378 -335
- package/dist/es/desensitized/index.d.ts +26 -23
- package/dist/es/desensitized/index.mjs +21 -18
- package/dist/es/device/index.d.ts +31 -25
- package/dist/es/device/index.mjs +33 -30
- package/dist/es/dom/index.d.ts +32 -29
- package/dist/es/dom/index.mjs +26 -23
- package/dist/es/file/index.d.ts +30 -30
- package/dist/es/file/index.mjs +51 -41
- package/dist/es/function/index.d.ts +10 -7
- package/dist/es/function/index.mjs +22 -19
- package/dist/es/id/index.d.ts +3 -0
- package/dist/es/id/index.mjs +6 -2
- package/dist/es/index.d.ts +24 -25
- package/dist/es/index.mjs +6 -23
- package/dist/es/keycode/index.d.ts +6 -6
- package/dist/es/keycode/index.mjs +9 -12
- package/dist/es/math/index.d.ts +37 -37
- package/dist/es/math/index.mjs +113 -81
- package/dist/es/number/index.d.ts +7 -7
- package/dist/es/number/index.mjs +10 -7
- package/dist/es/object/index.d.ts +20 -19
- package/dist/es/object/index.mjs +77 -30
- package/dist/es/pagination/index.d.ts +39 -6
- package/dist/es/pagination/index.mjs +25 -10
- package/dist/es/random/index.d.ts +10 -7
- package/dist/es/random/index.mjs +8 -5
- package/dist/es/regexp/index.d.ts +30 -30
- package/dist/es/regexp/index.mjs +23 -20
- package/dist/es/storage/index.d.ts +10 -4
- package/dist/es/storage/index.mjs +4 -1
- package/dist/es/storage/localStorage.d.ts +9 -9
- package/dist/es/storage/localStorage.mjs +5 -5
- package/dist/es/storage/sessionStorage.d.ts +9 -9
- package/dist/es/storage/sessionStorage.mjs +6 -6
- package/dist/es/string/index.d.ts +62 -59
- package/dist/es/string/index.mjs +66 -63
- package/dist/es/url/index.d.ts +65 -65
- package/dist/es/url/index.mjs +83 -80
- package/dist/es/validate/index.d.ts +83 -80
- package/dist/es/validate/index.mjs +122 -106
- package/dist/index.d.ts +2355 -2803
- package/dist/lib/index.full.umd.js +3297 -9474
- package/dist/lib/index.full.umd.min.js +2 -64
- package/dist/lib/index.full.umd.min.js.map +1 -1
- package/dist/resolver/auto-imports.cjs +38 -31
- package/dist/resolver/auto-imports.mjs +38 -31
- package/dist/resolver/index.cjs +1 -2
- package/dist/resolver/index.d.ts +1 -1
- package/dist/resolver/index.mjs +1 -2
- package/package.json +96 -90
- package/dist/cjs/crypto/aes/aes.cjs +0 -480
- package/dist/cjs/crypto/aes/index.cjs +0 -27
- package/dist/cjs/crypto/base32/base32.cjs +0 -357
- package/dist/cjs/crypto/base32/index.cjs +0 -41
- package/dist/cjs/crypto/des/des.cjs +0 -257
- package/dist/cjs/crypto/des/index.cjs +0 -28
- package/dist/cjs/crypto/sha/sha1/index.cjs +0 -24
- package/dist/cjs/crypto/sha/sha1/sha1.cjs +0 -529
- package/dist/cjs/crypto/sha/sha256/index.cjs +0 -43
- package/dist/cjs/crypto/sha/sha256/sha256.cjs +0 -595
- package/dist/cjs/crypto/sha/sha3/index.cjs +0 -41
- package/dist/cjs/crypto/sha/sha3/sha3.cjs +0 -624
- package/dist/cjs/crypto/sha/sha512/index.cjs +0 -81
- package/dist/cjs/crypto/sha/sha512/sha512.cjs +0 -950
- package/dist/cjs/crypto/sm/lib/asn1.cjs +0 -149
- package/dist/cjs/crypto/sm/lib/ec.cjs +0 -315
- package/dist/cjs/crypto/sm/lib/jsbn.cjs +0 -1608
- package/dist/cjs/crypto/sm/lib/sm3.cjs +0 -158
- package/dist/cjs/crypto/sm/lib/utils.cjs +0 -170
- package/dist/cjs/crypto/sm/sm2/index.cjs +0 -112
- package/dist/cjs/crypto/sm/sm2/sm2.cjs +0 -231
- package/dist/cjs/crypto/sm/sm3/index.cjs +0 -15
- package/dist/cjs/crypto/sm/sm3/sm3.cjs +0 -93
- package/dist/cjs/crypto/sm/sm4/index.cjs +0 -27
- package/dist/cjs/crypto/sm/sm4/sm4.cjs +0 -327
- package/dist/cjs/crypto/tea/index.cjs +0 -25
- package/dist/cjs/crypto/tea/tea.cjs +0 -187
- package/dist/cjs/weapp/index.cjs +0 -142
- package/dist/es/crypto/aes/aes.d.ts +0 -156
- package/dist/es/crypto/aes/aes.mjs +0 -478
- package/dist/es/crypto/aes/index.d.ts +0 -16
- package/dist/es/crypto/aes/index.mjs +0 -24
- package/dist/es/crypto/base32/base32.d.ts +0 -3
- package/dist/es/crypto/base32/base32.mjs +0 -353
- package/dist/es/crypto/base32/index.d.ts +0 -24
- package/dist/es/crypto/base32/index.mjs +0 -36
- package/dist/es/crypto/des/des.d.ts +0 -52
- package/dist/es/crypto/des/des.mjs +0 -255
- package/dist/es/crypto/des/index.d.ts +0 -14
- package/dist/es/crypto/des/index.mjs +0 -25
- package/dist/es/crypto/sha/index.d.ts +0 -4
- package/dist/es/crypto/sha/sha1/index.d.ts +0 -13
- package/dist/es/crypto/sha/sha1/index.mjs +0 -21
- package/dist/es/crypto/sha/sha1/sha1.d.ts +0 -2
- package/dist/es/crypto/sha/sha1/sha1.mjs +0 -526
- package/dist/es/crypto/sha/sha256/index.d.ts +0 -26
- package/dist/es/crypto/sha/sha256/index.mjs +0 -38
- package/dist/es/crypto/sha/sha256/sha256.d.ts +0 -4
- package/dist/es/crypto/sha/sha256/sha256.mjs +0 -590
- package/dist/es/crypto/sha/sha3/index.d.ts +0 -24
- package/dist/es/crypto/sha/sha3/index.mjs +0 -36
- package/dist/es/crypto/sha/sha3/sha3.d.ts +0 -4
- package/dist/es/crypto/sha/sha3/sha3.mjs +0 -619
- package/dist/es/crypto/sha/sha512/index.d.ts +0 -52
- package/dist/es/crypto/sha/sha512/index.mjs +0 -72
- package/dist/es/crypto/sha/sha512/sha512.d.ts +0 -8
- package/dist/es/crypto/sha/sha512/sha512.mjs +0 -941
- package/dist/es/crypto/sm/index.d.ts +0 -3
- package/dist/es/crypto/sm/lib/asn1.d.ts +0 -12
- package/dist/es/crypto/sm/lib/asn1.mjs +0 -146
- package/dist/es/crypto/sm/lib/ec.d.ts +0 -126
- package/dist/es/crypto/sm/lib/ec.mjs +0 -312
- package/dist/es/crypto/sm/lib/jsbn.d.ts +0 -198
- package/dist/es/crypto/sm/lib/jsbn.mjs +0 -1605
- package/dist/es/crypto/sm/lib/sm3.d.ts +0 -5
- package/dist/es/crypto/sm/lib/sm3.mjs +0 -155
- package/dist/es/crypto/sm/lib/utils.d.ts +0 -53
- package/dist/es/crypto/sm/lib/utils.mjs +0 -158
- package/dist/es/crypto/sm/sm2/index.d.ts +0 -71
- package/dist/es/crypto/sm/sm2/index.mjs +0 -101
- package/dist/es/crypto/sm/sm2/sm2.d.ts +0 -34
- package/dist/es/crypto/sm/sm2/sm2.mjs +0 -220
- package/dist/es/crypto/sm/sm3/index.d.ts +0 -7
- package/dist/es/crypto/sm/sm3/index.mjs +0 -13
- package/dist/es/crypto/sm/sm3/sm3.d.ts +0 -1
- package/dist/es/crypto/sm/sm3/sm3.mjs +0 -91
- package/dist/es/crypto/sm/sm4/index.d.ts +0 -16
- package/dist/es/crypto/sm/sm4/index.mjs +0 -24
- package/dist/es/crypto/sm/sm4/sm4.d.ts +0 -2
- package/dist/es/crypto/sm/sm4/sm4.mjs +0 -324
- package/dist/es/crypto/tea/index.d.ts +0 -14
- package/dist/es/crypto/tea/index.mjs +0 -22
- package/dist/es/crypto/tea/tea.d.ts +0 -69
- package/dist/es/crypto/tea/tea.mjs +0 -185
- package/dist/es/weapp/index.d.ts +0 -57
- package/dist/es/weapp/index.mjs +0 -131
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// ========== 常量定义(规范化,避免魔法值) ==========
|
|
4
|
+
const SM4_MODE_ECB = "ecb";
|
|
5
|
+
const SM4_MODE_CBC = "cbc";
|
|
6
|
+
const SM4_PADDING = "pkcs#7";
|
|
7
|
+
const SM4_OUTPUT_HEX = "hex";
|
|
8
|
+
const SM4_OUTPUT_UTF8 = "utf8";
|
|
9
|
+
const SM4_OUTPUT_ARRAY = "array";
|
|
10
|
+
const SM4_OUTPUT_UINT8ARRAY = "uint8array";
|
|
11
|
+
const SM4_OUTPUT_ARRAYBUFFER = "arraybuffer";
|
|
12
|
+
const ENCRYPT = 1;
|
|
13
|
+
const DECRYPT = 0;
|
|
14
|
+
const ROUND_COUNT = 32;
|
|
15
|
+
const BLOCK_SIZE = 16; // 128比特 = 16字节
|
|
16
|
+
const KEY_SIZE = 16; // SM4密钥固定128比特
|
|
17
|
+
const IV_SIZE = 16; // CBC模式IV固定128比特
|
|
18
|
+
// SM4 S盒
|
|
19
|
+
const SBOX = new Uint8Array([
|
|
20
|
+
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a,
|
|
21
|
+
0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef,
|
|
22
|
+
0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80,
|
|
23
|
+
0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19,
|
|
24
|
+
0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d,
|
|
25
|
+
0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00,
|
|
26
|
+
0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40,
|
|
27
|
+
0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
|
|
28
|
+
0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23,
|
|
29
|
+
0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c,
|
|
30
|
+
0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a,
|
|
31
|
+
0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a,
|
|
32
|
+
0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d,
|
|
33
|
+
0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
|
|
34
|
+
]);
|
|
35
|
+
// 轮常量 CK
|
|
36
|
+
const CK = new Uint32Array([
|
|
37
|
+
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5,
|
|
38
|
+
0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1,
|
|
39
|
+
0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed,
|
|
40
|
+
0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,
|
|
41
|
+
]);
|
|
42
|
+
// 系统参数 FK
|
|
43
|
+
const FK = new Uint32Array([0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]);
|
|
44
|
+
// ========== 工具函数(通用转换) ==========
|
|
45
|
+
/**
|
|
46
|
+
* 16进制字符串转Uint8Array
|
|
47
|
+
* @param {string} str - 16进制字符串
|
|
48
|
+
* @returns {Uint8Array} 字节数组
|
|
49
|
+
*/
|
|
50
|
+
function hexToUint8Array(str) {
|
|
51
|
+
str = str.replace(/\s+/g, ""); // 去除空格
|
|
52
|
+
if (str.length % 2 !== 0)
|
|
53
|
+
throw new Error("Hex string length must be even");
|
|
54
|
+
const arr = new Uint8Array(str.length / 2);
|
|
55
|
+
for (let i = 0; i < str.length; i += 2) {
|
|
56
|
+
arr[i / 2] = parseInt(str.substr(i, 2), 16) & 0xff;
|
|
57
|
+
}
|
|
58
|
+
return arr;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Uint8Array转16进制字符串
|
|
62
|
+
* @param {Uint8Array} arr - 字节数组
|
|
63
|
+
* @returns {string} 16进制字符串
|
|
64
|
+
*/
|
|
65
|
+
function uint8ArrayToHex(arr) {
|
|
66
|
+
return Array.from(arr)
|
|
67
|
+
.map((byte) => {
|
|
68
|
+
const hex = byte.toString(16);
|
|
69
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
70
|
+
})
|
|
71
|
+
.join("");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* UTF8字符串转Uint8Array
|
|
75
|
+
* @param {string} str - UTF8字符串
|
|
76
|
+
* @returns {Uint8Array} 字节数组
|
|
77
|
+
*/
|
|
78
|
+
function utf8ToUint8Array(str) {
|
|
79
|
+
return new TextEncoder().encode(str);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Uint8Array转UTF8字符串
|
|
83
|
+
* @param {Uint8Array} arr - 字节数组
|
|
84
|
+
* @returns {string} UTF8字符串
|
|
85
|
+
*/
|
|
86
|
+
function uint8ArrayToUtf8(arr) {
|
|
87
|
+
return new TextDecoder("utf-8").decode(arr);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 统一输入数据格式为Uint8Array
|
|
91
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} input - 输入数据
|
|
92
|
+
* @param {number} cryptFlag - ENCRYPT/DECRYPT
|
|
93
|
+
* @returns {Uint8Array} 标准化后的字节数组
|
|
94
|
+
*/
|
|
95
|
+
function normalizeInput(input, cryptFlag) {
|
|
96
|
+
if (input instanceof ArrayBuffer) {
|
|
97
|
+
return new Uint8Array(input);
|
|
98
|
+
}
|
|
99
|
+
if (input instanceof Uint8Array) {
|
|
100
|
+
return new Uint8Array(input); // 拷贝避免修改原数组
|
|
101
|
+
}
|
|
102
|
+
if (Array.isArray(input)) {
|
|
103
|
+
return new Uint8Array(input);
|
|
104
|
+
}
|
|
105
|
+
if (typeof input === "string") {
|
|
106
|
+
if (cryptFlag === ENCRYPT) {
|
|
107
|
+
// 加密:字符串按UTF8转字节
|
|
108
|
+
return utf8ToUint8Array(input);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// 解密:字符串按16进制转字节
|
|
112
|
+
return hexToUint8Array(input);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Unsupported input type: ${typeof input}`);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 标准化密钥/IV为Uint8Array
|
|
119
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} keyOrIv - 密钥/IV
|
|
120
|
+
* @param {number} expectedLength - 期望长度(字节)
|
|
121
|
+
* @param {string} name - 名称(用于报错)
|
|
122
|
+
* @returns {Uint8Array} 标准化后的字节数组
|
|
123
|
+
*/
|
|
124
|
+
function normalizeKeyIv(keyOrIv, expectedLength, name) {
|
|
125
|
+
let arr;
|
|
126
|
+
if (typeof keyOrIv === "string") {
|
|
127
|
+
arr = hexToUint8Array(keyOrIv);
|
|
128
|
+
}
|
|
129
|
+
else if (keyOrIv instanceof ArrayBuffer) {
|
|
130
|
+
arr = new Uint8Array(keyOrIv);
|
|
131
|
+
}
|
|
132
|
+
else if (keyOrIv instanceof Uint8Array) {
|
|
133
|
+
arr = keyOrIv;
|
|
134
|
+
}
|
|
135
|
+
else if (Array.isArray(keyOrIv)) {
|
|
136
|
+
arr = new Uint8Array(keyOrIv);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
throw new Error(`Unsupported ${name} type: ${typeof keyOrIv}`);
|
|
140
|
+
}
|
|
141
|
+
if (arr.length !== expectedLength) {
|
|
142
|
+
throw new Error(`${name} must be ${expectedLength * 8} bits (${expectedLength} bytes)`);
|
|
143
|
+
}
|
|
144
|
+
return arr;
|
|
145
|
+
}
|
|
146
|
+
// ========== SM4核心函数 ==========
|
|
147
|
+
/**
|
|
148
|
+
* 32比特循环左移
|
|
149
|
+
* @param {number} x - 32比特无符号整数
|
|
150
|
+
* @param {number} n - 移位位数
|
|
151
|
+
* @returns {number} 移位结果
|
|
152
|
+
*/
|
|
153
|
+
function rotl32(x, n) {
|
|
154
|
+
const s = n & 31;
|
|
155
|
+
return ((x << s) | (x >>> (32 - s))) >>> 0; // >>>0 确保无符号
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 非线性变换(字节替换)
|
|
159
|
+
* @param {number} a - 32比特无符号整数
|
|
160
|
+
* @returns {number} 替换结果
|
|
161
|
+
*/
|
|
162
|
+
function byteSub(a) {
|
|
163
|
+
return (((SBOX[(a >>> 24) & 0xff] << 24) |
|
|
164
|
+
(SBOX[(a >>> 16) & 0xff] << 16) |
|
|
165
|
+
(SBOX[(a >>> 8) & 0xff] << 8) |
|
|
166
|
+
SBOX[a & 0xff]) >>>
|
|
167
|
+
0);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 线性变换(加密/解密用)
|
|
171
|
+
* @param {number} b - 32比特无符号整数
|
|
172
|
+
* @returns {number} 变换结果
|
|
173
|
+
*/
|
|
174
|
+
function linearTransformEnc(b) {
|
|
175
|
+
return (b ^ rotl32(b, 2) ^ rotl32(b, 10) ^ rotl32(b, 18) ^ rotl32(b, 24)) >>> 0;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 线性变换(密钥扩展用)
|
|
179
|
+
* @param {number} b - 32比特无符号整数
|
|
180
|
+
* @returns {number} 变换结果
|
|
181
|
+
*/
|
|
182
|
+
function linearTransformKey(b) {
|
|
183
|
+
return (b ^ rotl32(b, 13) ^ rotl32(b, 23)) >>> 0;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* SM4单块加密/解密(128比特)
|
|
187
|
+
* @param {Uint8Array} inputBlock - 输入块(16字节)
|
|
188
|
+
* @param {Uint8Array} outputBlock - 输出块(16字节)
|
|
189
|
+
* @param {Uint32Array} roundKeys - 轮密钥(32个32比特)
|
|
190
|
+
*/
|
|
191
|
+
function sm4BlockCrypt(inputBlock, outputBlock, roundKeys) {
|
|
192
|
+
// 确保输入块是16字节
|
|
193
|
+
if (inputBlock.length !== BLOCK_SIZE) {
|
|
194
|
+
throw new Error(`Input block must be ${BLOCK_SIZE} bytes for SM4 block crypt`);
|
|
195
|
+
}
|
|
196
|
+
// 字节数组转32比特字数组(4个字,共128比特)
|
|
197
|
+
const x = new Uint32Array(4);
|
|
198
|
+
for (let i = 0; i < 4; i++) {
|
|
199
|
+
const offset = 4 * i;
|
|
200
|
+
x[i] =
|
|
201
|
+
((inputBlock[offset] << 24) |
|
|
202
|
+
(inputBlock[offset + 1] << 16) |
|
|
203
|
+
(inputBlock[offset + 2] << 8) |
|
|
204
|
+
inputBlock[offset + 3]) >>>
|
|
205
|
+
0;
|
|
206
|
+
}
|
|
207
|
+
// 32轮加密
|
|
208
|
+
for (let r = 0; r < ROUND_COUNT; r += 4) {
|
|
209
|
+
let mid = (x[1] ^ x[2] ^ x[3] ^ roundKeys[r]) >>> 0;
|
|
210
|
+
x[0] ^= linearTransformEnc(byteSub(mid));
|
|
211
|
+
mid = (x[2] ^ x[3] ^ x[0] ^ roundKeys[r + 1]) >>> 0;
|
|
212
|
+
x[1] ^= linearTransformEnc(byteSub(mid));
|
|
213
|
+
mid = (x[3] ^ x[0] ^ x[1] ^ roundKeys[r + 2]) >>> 0;
|
|
214
|
+
x[2] ^= linearTransformEnc(byteSub(mid));
|
|
215
|
+
mid = (x[0] ^ x[1] ^ x[2] ^ roundKeys[r + 3]) >>> 0;
|
|
216
|
+
x[3] ^= linearTransformEnc(byteSub(mid));
|
|
217
|
+
}
|
|
218
|
+
// 反序输出
|
|
219
|
+
for (let j = 0; j < BLOCK_SIZE; j += 4) {
|
|
220
|
+
const wordIdx = 3 - j / 4;
|
|
221
|
+
outputBlock[j] = (x[wordIdx] >>> 24) & 0xff;
|
|
222
|
+
outputBlock[j + 1] = (x[wordIdx] >>> 16) & 0xff;
|
|
223
|
+
outputBlock[j + 2] = (x[wordIdx] >>> 8) & 0xff;
|
|
224
|
+
outputBlock[j + 3] = x[wordIdx] & 0xff;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* SM4密钥扩展算法
|
|
229
|
+
* @param {Uint8Array} key - 16字节密钥
|
|
230
|
+
* @param {Uint32Array} roundKeys - 输出轮密钥(32个32比特)
|
|
231
|
+
* @param {number} cryptFlag - ENCRYPT/DECRYPT
|
|
232
|
+
*/
|
|
233
|
+
function sm4KeyExpansion(key, roundKeys, cryptFlag) {
|
|
234
|
+
// 密钥转32比特字数组
|
|
235
|
+
const x = new Uint32Array(4);
|
|
236
|
+
for (let i = 0; i < 4; i++) {
|
|
237
|
+
const offset = 4 * i;
|
|
238
|
+
x[i] = ((key[offset] << 24) | (key[offset + 1] << 16) | (key[offset + 2] << 8) | key[offset + 3]) >>> 0;
|
|
239
|
+
}
|
|
240
|
+
// 与系统参数异或
|
|
241
|
+
x[0] ^= FK[0];
|
|
242
|
+
x[1] ^= FK[1];
|
|
243
|
+
x[2] ^= FK[2];
|
|
244
|
+
x[3] ^= FK[3];
|
|
245
|
+
// 生成轮密钥
|
|
246
|
+
for (let r = 0; r < ROUND_COUNT; r += 4) {
|
|
247
|
+
let mid = (x[1] ^ x[2] ^ x[3] ^ CK[r]) >>> 0;
|
|
248
|
+
roundKeys[r] = x[0] ^= linearTransformKey(byteSub(mid));
|
|
249
|
+
mid = (x[2] ^ x[3] ^ x[0] ^ CK[r + 1]) >>> 0;
|
|
250
|
+
roundKeys[r + 1] = x[1] ^= linearTransformKey(byteSub(mid));
|
|
251
|
+
mid = (x[3] ^ x[0] ^ x[1] ^ CK[r + 2]) >>> 0;
|
|
252
|
+
roundKeys[r + 2] = x[2] ^= linearTransformKey(byteSub(mid));
|
|
253
|
+
mid = (x[0] ^ x[1] ^ x[2] ^ CK[r + 3]) >>> 0;
|
|
254
|
+
roundKeys[r + 3] = x[3] ^= linearTransformKey(byteSub(mid));
|
|
255
|
+
}
|
|
256
|
+
// 解密时轮密钥反序
|
|
257
|
+
if (cryptFlag === DECRYPT) {
|
|
258
|
+
for (let r = 0; r < 16; r++) {
|
|
259
|
+
const temp = roundKeys[r];
|
|
260
|
+
roundKeys[r] = roundKeys[31 - r];
|
|
261
|
+
roundKeys[31 - r] = temp;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* PKCS#7填充
|
|
267
|
+
* @param {Uint8Array} data - 原始数据
|
|
268
|
+
* @returns {Uint8Array} 填充后的数据
|
|
269
|
+
*/
|
|
270
|
+
function pkcs7Pad(data) {
|
|
271
|
+
const paddingCount = BLOCK_SIZE - (data.length % BLOCK_SIZE);
|
|
272
|
+
const padded = new Uint8Array(data.length + paddingCount);
|
|
273
|
+
padded.set(data);
|
|
274
|
+
for (let i = 0; i < paddingCount; i++) {
|
|
275
|
+
padded[data.length + i] = paddingCount & 0xff;
|
|
276
|
+
}
|
|
277
|
+
return padded;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* PKCS#7去填充
|
|
281
|
+
* @param {Uint8Array} data - 填充后的数据
|
|
282
|
+
* @returns {Uint8Array} 去填充后的数据
|
|
283
|
+
*/
|
|
284
|
+
function pkcs7Unpad(data) {
|
|
285
|
+
const paddingCount = data[data.length - 1] & 0xff;
|
|
286
|
+
// 验证填充合法性
|
|
287
|
+
for (let i = 1; i <= paddingCount; i++) {
|
|
288
|
+
if (data[data.length - i] !== paddingCount) {
|
|
289
|
+
throw new Error("Invalid PKCS#7 padding");
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return data.subarray(0, data.length - paddingCount);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* SM4主函数
|
|
296
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} inputData - 输入数据
|
|
297
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} key - 16字节密钥
|
|
298
|
+
* @param {number} cryptFlag - ENCRYPT/DECRYPT
|
|
299
|
+
* @param {Object} [options] - 选项
|
|
300
|
+
* @param {string} [options.mode=ecb] - 模式:ecb/cbc
|
|
301
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} [options.iv] - CBC模式IV(16字节)
|
|
302
|
+
* @param {string} [options.padding=pkcs#7] - 填充方式:pkcs#7
|
|
303
|
+
* @param {string} [options.output] - 输出格式:hex/utf8/array/uint8array/arraybuffer
|
|
304
|
+
* @returns {string|Array|Uint8Array|ArrayBuffer} 输出数据
|
|
305
|
+
*/
|
|
306
|
+
function sm4Core(inputData, key, cryptFlag, options = {}) {
|
|
307
|
+
// 默认参数(加密和解密默认输出都为hex,避免格式不匹配)
|
|
308
|
+
const { mode = SM4_MODE_ECB, iv = [], padding = SM4_PADDING, output = SM4_OUTPUT_HEX, // 统一默认hex格式
|
|
309
|
+
} = options;
|
|
310
|
+
// 校验模式
|
|
311
|
+
if (![SM4_MODE_ECB, SM4_MODE_CBC].includes(mode)) {
|
|
312
|
+
throw new Error(`Unsupported mode: ${mode}, only 'ecb' and 'cbc' are supported`);
|
|
313
|
+
}
|
|
314
|
+
// 标准化输入、密钥、IV
|
|
315
|
+
const input = normalizeInput(inputData, cryptFlag);
|
|
316
|
+
const keyBytes = normalizeKeyIv(key, KEY_SIZE, "key");
|
|
317
|
+
let ivBytes = new Uint8Array(IV_SIZE);
|
|
318
|
+
if (mode === SM4_MODE_CBC) {
|
|
319
|
+
ivBytes = normalizeKeyIv(iv, IV_SIZE, "IV");
|
|
320
|
+
}
|
|
321
|
+
// 填充(仅加密时)
|
|
322
|
+
let processedInput = input;
|
|
323
|
+
if (padding === SM4_PADDING && cryptFlag === ENCRYPT) {
|
|
324
|
+
processedInput = pkcs7Pad(input);
|
|
325
|
+
// 确保填充后是16字节的倍数
|
|
326
|
+
if (processedInput.length % BLOCK_SIZE !== 0) {
|
|
327
|
+
throw new Error("PKCS7 padding failed: data length is not multiple of block size");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// 生成轮密钥
|
|
331
|
+
const roundKeys = new Uint32Array(ROUND_COUNT);
|
|
332
|
+
sm4KeyExpansion(keyBytes, roundKeys, cryptFlag);
|
|
333
|
+
// 初始化输出缓冲区
|
|
334
|
+
const outputData = new Uint8Array(processedInput.length);
|
|
335
|
+
let lastVector = new Uint8Array(ivBytes); // CBC模式向量
|
|
336
|
+
let point = 0;
|
|
337
|
+
// 分块处理(严格按16字节分块)
|
|
338
|
+
while (point < processedInput.length) {
|
|
339
|
+
const inputBlock = processedInput.subarray(point, point + BLOCK_SIZE);
|
|
340
|
+
const outputBlock = new Uint8Array(BLOCK_SIZE);
|
|
341
|
+
if (mode === SM4_MODE_CBC) {
|
|
342
|
+
if (cryptFlag === ENCRYPT) {
|
|
343
|
+
// CBC加密:输入块与前向量异或
|
|
344
|
+
const xorBlock = new Uint8Array(BLOCK_SIZE);
|
|
345
|
+
for (let i = 0; i < BLOCK_SIZE; i++) {
|
|
346
|
+
xorBlock[i] = (inputBlock[i] ^ lastVector[i]) & 0xff;
|
|
347
|
+
}
|
|
348
|
+
sm4BlockCrypt(xorBlock, outputBlock, roundKeys);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
// CBC解密:先加密再异或
|
|
352
|
+
sm4BlockCrypt(inputBlock, outputBlock, roundKeys);
|
|
353
|
+
for (let i = 0; i < BLOCK_SIZE; i++) {
|
|
354
|
+
outputBlock[i] = (outputBlock[i] ^ lastVector[i]) & 0xff;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// 更新向量
|
|
358
|
+
lastVector = cryptFlag === ENCRYPT ? outputBlock : inputBlock;
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
// ECB模式(严格调用块加密)
|
|
362
|
+
sm4BlockCrypt(inputBlock, outputBlock, roundKeys);
|
|
363
|
+
}
|
|
364
|
+
// 写入输出
|
|
365
|
+
outputData.set(outputBlock, point);
|
|
366
|
+
point += BLOCK_SIZE;
|
|
367
|
+
}
|
|
368
|
+
// 去填充(仅解密时)
|
|
369
|
+
let finalOutput = outputData;
|
|
370
|
+
if (padding === SM4_PADDING && cryptFlag === DECRYPT) {
|
|
371
|
+
finalOutput = pkcs7Unpad(outputData);
|
|
372
|
+
}
|
|
373
|
+
// 转换输出格式(解密时如果输出是utf8,先转hex再转utf8)
|
|
374
|
+
if (cryptFlag === DECRYPT && output === SM4_OUTPUT_UTF8) {
|
|
375
|
+
return uint8ArrayToUtf8(finalOutput);
|
|
376
|
+
}
|
|
377
|
+
switch (output) {
|
|
378
|
+
case SM4_OUTPUT_HEX:
|
|
379
|
+
return uint8ArrayToHex(finalOutput);
|
|
380
|
+
case SM4_OUTPUT_ARRAY:
|
|
381
|
+
return Array.from(finalOutput);
|
|
382
|
+
case SM4_OUTPUT_UINT8ARRAY:
|
|
383
|
+
return finalOutput;
|
|
384
|
+
case SM4_OUTPUT_ARRAYBUFFER:
|
|
385
|
+
return finalOutput.buffer;
|
|
386
|
+
default:
|
|
387
|
+
throw new Error(`Unsupported output format: ${output}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// ========== 便捷API(函数式,符合设计准则) ==========
|
|
391
|
+
/**
|
|
392
|
+
* 生成 SM4 CBC 模式专用的安全随机 IV(16字节)
|
|
393
|
+
* @param {string} [outputFormat=SM4_OUTPUT_HEX] - 输出格式:hex/uint8array/array/arraybuffer
|
|
394
|
+
* @returns {string|Uint8Array|Array|ArrayBuffer} 随机IV
|
|
395
|
+
*/
|
|
396
|
+
function generateIv(outputFormat = SM4_OUTPUT_HEX) {
|
|
397
|
+
// 1. 校验浏览器是否支持 crypto
|
|
398
|
+
if (!window?.crypto?.getRandomValues) {
|
|
399
|
+
throw new Error("Your browser does not support secure random generation (crypto API)");
|
|
400
|
+
}
|
|
401
|
+
// 2. 生成 16 字节安全随机数
|
|
402
|
+
const ivUint8 = new Uint8Array(IV_SIZE);
|
|
403
|
+
window.crypto.getRandomValues(ivUint8);
|
|
404
|
+
// 3. 用导出的常量做格式判断,新增 ArrayBuffer 支持
|
|
405
|
+
switch (outputFormat) {
|
|
406
|
+
case SM4_OUTPUT_UINT8ARRAY:
|
|
407
|
+
return ivUint8;
|
|
408
|
+
case SM4_OUTPUT_ARRAY:
|
|
409
|
+
return Array.from(ivUint8).map((byte) => Number(byte));
|
|
410
|
+
case SM4_OUTPUT_ARRAYBUFFER: // 新增:支持 ArrayBuffer 格式
|
|
411
|
+
return ivUint8.buffer;
|
|
412
|
+
case SM4_OUTPUT_HEX:
|
|
413
|
+
default:
|
|
414
|
+
return Array.from(ivUint8)
|
|
415
|
+
.map((byte) => {
|
|
416
|
+
const hex = byte.toString(16);
|
|
417
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
418
|
+
})
|
|
419
|
+
.join("");
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* 生成 SM4 标准密钥(16字节/32位16进制字符串)
|
|
424
|
+
* @param {string} [outputFormat=SM4_OUTPUT_HEX] - 输出格式:hex/uint8array/array/arraybuffer
|
|
425
|
+
* @returns {string|Uint8Array|number[]|ArrayBuffer} 16字节SM4密钥
|
|
426
|
+
*/
|
|
427
|
+
function generateKey(outputFormat = SM4_OUTPUT_HEX) {
|
|
428
|
+
// 校验浏览器/Node环境的安全随机数API
|
|
429
|
+
if (!window?.crypto?.getRandomValues && !global?.crypto?.getRandomValues) {
|
|
430
|
+
throw new Error("当前环境不支持安全随机数生成,请升级浏览器/Node.js");
|
|
431
|
+
}
|
|
432
|
+
// 生成16字节随机数(SM4密钥固定16字节)
|
|
433
|
+
const cryptoObj = window?.crypto || global?.crypto;
|
|
434
|
+
const keyUint8 = new Uint8Array(16);
|
|
435
|
+
cryptoObj.getRandomValues(keyUint8);
|
|
436
|
+
// 按格式返回(用常量替代硬编码字符串,新增 ArrayBuffer 支持)
|
|
437
|
+
switch (outputFormat) {
|
|
438
|
+
case SM4_OUTPUT_UINT8ARRAY:
|
|
439
|
+
return keyUint8;
|
|
440
|
+
case SM4_OUTPUT_ARRAY:
|
|
441
|
+
return Array.from(keyUint8).map((byte) => Number(byte));
|
|
442
|
+
case SM4_OUTPUT_ARRAYBUFFER: // 新增:支持 ArrayBuffer 格式
|
|
443
|
+
return keyUint8.buffer;
|
|
444
|
+
case SM4_OUTPUT_HEX:
|
|
445
|
+
default:
|
|
446
|
+
return Array.from(keyUint8)
|
|
447
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
448
|
+
.join("");
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* SM4加密
|
|
453
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} input - 输入数据(字符串/字节)
|
|
454
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} key - 16字节密钥
|
|
455
|
+
* @param {Object} [options] - 选项
|
|
456
|
+
* @returns {string|Array|Uint8Array|ArrayBuffer} 加密结果
|
|
457
|
+
*/
|
|
458
|
+
function encrypt(input, key, options = {}) {
|
|
459
|
+
return sm4Core(input, key, ENCRYPT, options);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* SM4解密
|
|
463
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} input - 加密数据(16进制字符串/字节)
|
|
464
|
+
* @param {string|Array|Uint8Array|ArrayBuffer} key - 16字节密钥
|
|
465
|
+
* @param {Object} [options] - 选项
|
|
466
|
+
* @returns {string|Array|Uint8Array|ArrayBuffer} 解密结果
|
|
467
|
+
*/
|
|
468
|
+
function decrypt(input, key, options = {}) {
|
|
469
|
+
// 解密时如果没传output,默认按加密的output格式(hex)处理,再转utf8
|
|
470
|
+
const finalOptions = {
|
|
471
|
+
output: SM4_OUTPUT_UTF8, // 解密默认返回utf8字符串
|
|
472
|
+
...options,
|
|
473
|
+
};
|
|
474
|
+
return sm4Core(input, key, DECRYPT, finalOptions);
|
|
475
|
+
}
|
|
476
|
+
// 导出模式
|
|
477
|
+
const MODE = {
|
|
478
|
+
ECB: SM4_MODE_ECB,
|
|
479
|
+
CBC: SM4_MODE_CBC,
|
|
480
|
+
};
|
|
481
|
+
// 导出填充
|
|
482
|
+
const PADDING = SM4_PADDING;
|
|
483
|
+
// 导出输出模式
|
|
484
|
+
const OUTPUT = {
|
|
485
|
+
HEX: SM4_OUTPUT_HEX,
|
|
486
|
+
UTF8: SM4_OUTPUT_UTF8,
|
|
487
|
+
ARRAY: SM4_OUTPUT_ARRAY,
|
|
488
|
+
UINT8ARRAY: SM4_OUTPUT_UINT8ARRAY,
|
|
489
|
+
ARRAYBUFFER: SM4_OUTPUT_ARRAYBUFFER,
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
exports.MODE = MODE;
|
|
493
|
+
exports.OUTPUT = OUTPUT;
|
|
494
|
+
exports.PADDING = PADDING;
|
|
495
|
+
exports.decrypt = decrypt;
|
|
496
|
+
exports.encrypt = encrypt;
|
|
497
|
+
exports.generateIv = generateIv;
|
|
498
|
+
exports.generateKey = generateKey;
|