@maiyunnet/kebab 2.0.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/.VSCodeCounter/2025-02-14_14-46-44/details.md +82 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +15 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +2 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +19 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +22 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +69 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.json +1 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.md +48 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +118 -0
- package/.vscode/tasks.json +15 -0
- package/LICENSE +201 -0
- package/README.md +201 -0
- package/bin/kebab.js +2 -0
- package/eslint.config.js +22 -0
- package/index.js +19 -0
- package/index.ts +33 -0
- package/lib/buffer.js +108 -0
- package/lib/buffer.ts +152 -0
- package/lib/captcha/zcool-addict-italic.ttf +0 -0
- package/lib/captcha.js +71 -0
- package/lib/captcha.ts +63 -0
- package/lib/consistent.js +171 -0
- package/lib/consistent.ts +219 -0
- package/lib/core.js +663 -0
- package/lib/core.ts +880 -0
- package/lib/crypto.js +256 -0
- package/lib/crypto.ts +384 -0
- package/lib/db.js +521 -0
- package/lib/db.ts +719 -0
- package/lib/dns.js +321 -0
- package/lib/dns.ts +405 -0
- package/lib/fs.js +405 -0
- package/lib/fs.ts +527 -0
- package/lib/jwt.js +223 -0
- package/lib/jwt.ts +276 -0
- package/lib/kv.js +1004 -0
- package/lib/kv.ts +1489 -0
- package/lib/lan.js +99 -0
- package/lib/lan.ts +87 -0
- package/lib/net/cacert.pem +3480 -0
- package/lib/net/formdata.js +137 -0
- package/lib/net/formdata.ts +166 -0
- package/lib/net/request.js +102 -0
- package/lib/net/request.ts +150 -0
- package/lib/net/response.js +28 -0
- package/lib/net/response.ts +59 -0
- package/lib/net.js +462 -0
- package/lib/net.ts +662 -0
- package/lib/s3.js +180 -0
- package/lib/s3.ts +235 -0
- package/lib/scan.js +276 -0
- package/lib/scan.ts +364 -0
- package/lib/session.js +177 -0
- package/lib/session.ts +230 -0
- package/lib/sql.js +818 -0
- package/lib/sql.ts +1151 -0
- package/lib/ssh/sftp.js +373 -0
- package/lib/ssh/sftp.ts +508 -0
- package/lib/ssh/shell.js +109 -0
- package/lib/ssh/shell.ts +123 -0
- package/lib/ssh.js +171 -0
- package/lib/ssh.ts +191 -0
- package/lib/text/tld.json +1 -0
- package/lib/text.js +452 -0
- package/lib/text.ts +607 -0
- package/lib/time.js +216 -0
- package/lib/time.ts +254 -0
- package/lib/ws.js +373 -0
- package/lib/ws.ts +523 -0
- package/lib/zip.js +381 -0
- package/lib/zip.ts +447 -0
- package/lib/zlib.js +289 -0
- package/lib/zlib.ts +350 -0
- package/main.js +51 -0
- package/main.ts +27 -0
- package/package.json +37 -0
- package/sys/child.js +585 -0
- package/sys/child.ts +678 -0
- package/sys/cmd.js +226 -0
- package/sys/cmd.ts +225 -0
- package/sys/ctr.js +608 -0
- package/sys/ctr.ts +904 -0
- package/sys/master.js +314 -0
- package/sys/master.ts +355 -0
- package/sys/mod.js +1273 -0
- package/sys/mod.ts +1871 -0
- package/sys/route.js +922 -0
- package/sys/route.ts +1113 -0
- package/types/index.d.ts +283 -0
- package/www/example/ctr/main.js +42 -0
- package/www/example/ctr/main.ts +9 -0
- package/www/example/ctr/middle.js +57 -0
- package/www/example/ctr/middle.ts +26 -0
- package/www/example/ctr/test.js +2818 -0
- package/www/example/ctr/test.ts +3218 -0
- package/www/example/data/locale/en.test.json +8 -0
- package/www/example/data/locale/index.html +1 -0
- package/www/example/data/locale/ja.test.json +8 -0
- package/www/example/data/locale/sc.test.json +8 -0
- package/www/example/data/locale/tc.test.json +8 -0
- package/www/example/data/test.zip +0 -0
- package/www/example/kebab.json +24 -0
- package/www/example/mod/test.js +49 -0
- package/www/example/mod/test.ts +47 -0
- package/www/example/mod/testdata.js +11 -0
- package/www/example/mod/testdata.ts +30 -0
- package/www/example/route.json +6 -0
- package/www/example/view/test.ejs +11 -0
- package/www/example/ws/mproxy.js +49 -0
- package/www/example/ws/mproxy.ts +16 -0
- package/www/example/ws/rproxy.js +47 -0
- package/www/example/ws/rproxy.ts +14 -0
- package/www/example/ws/test.js +68 -0
- package/www/example/ws/test.ts +36 -0
package/lib/crypto.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SM4_CFB = exports.SM4_CBC = exports.SM4_ECB = exports.AES_256_CFB = exports.AES_256_CBC = exports.AES_256_ECB = void 0;
|
|
37
|
+
exports.generateKeyPair = generateKeyPair;
|
|
38
|
+
exports.sign = sign;
|
|
39
|
+
exports.verify = verify;
|
|
40
|
+
exports.publicEncrypt = publicEncrypt;
|
|
41
|
+
exports.privateEncrypt = privateEncrypt;
|
|
42
|
+
exports.publicDecrypt = publicDecrypt;
|
|
43
|
+
exports.privateDecrypt = privateDecrypt;
|
|
44
|
+
exports.cipherEncrypt = cipherEncrypt;
|
|
45
|
+
exports.aesEncrypt = aesEncrypt;
|
|
46
|
+
exports.sm4Encrypt = sm4Encrypt;
|
|
47
|
+
exports.cipherDecrypt = cipherDecrypt;
|
|
48
|
+
exports.aesDecrypt = aesDecrypt;
|
|
49
|
+
exports.sm4Decrypt = sm4Decrypt;
|
|
50
|
+
exports.hashHmac = hashHmac;
|
|
51
|
+
exports.hashHmacFile = hashHmacFile;
|
|
52
|
+
exports.base64Encode = base64Encode;
|
|
53
|
+
exports.base64Decode = base64Decode;
|
|
54
|
+
exports.uuid = uuid;
|
|
55
|
+
const crypto = __importStar(require("crypto"));
|
|
56
|
+
const fs = __importStar(require("~/lib/fs"));
|
|
57
|
+
function generateKeyPair(type, options = {}) {
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
if (options.modulusLength === undefined) {
|
|
60
|
+
options.modulusLength = 2048;
|
|
61
|
+
}
|
|
62
|
+
if (options.namedCurve !== undefined) {
|
|
63
|
+
options.namedCurve = options.namedCurve.toUpperCase();
|
|
64
|
+
}
|
|
65
|
+
if (options.publicKeyEncoding === undefined) {
|
|
66
|
+
options.publicKeyEncoding = {
|
|
67
|
+
'format': 'pem',
|
|
68
|
+
'type': 'spki'
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (options.publicKeyEncoding.type === undefined) {
|
|
72
|
+
options.publicKeyEncoding.type = 'spki';
|
|
73
|
+
}
|
|
74
|
+
if (options.publicKeyEncoding.format === undefined) {
|
|
75
|
+
options.publicKeyEncoding.format = 'pem';
|
|
76
|
+
}
|
|
77
|
+
if (options.privateKeyEncoding === undefined) {
|
|
78
|
+
options.privateKeyEncoding = {
|
|
79
|
+
'format': 'pem',
|
|
80
|
+
'type': 'pkcs8'
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (options.privateKeyEncoding.type === undefined) {
|
|
84
|
+
options.privateKeyEncoding.type = 'pkcs8';
|
|
85
|
+
}
|
|
86
|
+
if (options.privateKeyEncoding.format === undefined) {
|
|
87
|
+
options.privateKeyEncoding.format = 'pem';
|
|
88
|
+
}
|
|
89
|
+
crypto.generateKeyPair(type, options, (err, publicKey, privateKey) => {
|
|
90
|
+
resolve({
|
|
91
|
+
'private': privateKey,
|
|
92
|
+
'public': publicKey
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function sign(data, privateKey, format = 'buffer', algorithm = 'sha256') {
|
|
98
|
+
const sign = crypto.createSign(algorithm);
|
|
99
|
+
sign.update(data);
|
|
100
|
+
return format === 'buffer' ? sign.sign(privateKey) : sign.sign(privateKey, format);
|
|
101
|
+
}
|
|
102
|
+
function verify(data, object, signature, algorithm = 'sha256') {
|
|
103
|
+
const verify = crypto.createVerify(algorithm);
|
|
104
|
+
verify.update(data);
|
|
105
|
+
return verify.verify(object, signature);
|
|
106
|
+
}
|
|
107
|
+
function publicEncrypt(key, buffer) {
|
|
108
|
+
return crypto.publicEncrypt(key, buffer);
|
|
109
|
+
}
|
|
110
|
+
function privateEncrypt(key, buffer) {
|
|
111
|
+
return crypto.privateEncrypt(key, buffer);
|
|
112
|
+
}
|
|
113
|
+
function publicDecrypt(key, buffer) {
|
|
114
|
+
return crypto.publicDecrypt(key, buffer);
|
|
115
|
+
}
|
|
116
|
+
function privateDecrypt(key, buffer) {
|
|
117
|
+
return crypto.privateDecrypt(key, buffer);
|
|
118
|
+
}
|
|
119
|
+
exports.AES_256_ECB = 'AES-256-ECB';
|
|
120
|
+
exports.AES_256_CBC = 'AES-256-CBC';
|
|
121
|
+
exports.AES_256_CFB = 'AES-256-CFB';
|
|
122
|
+
exports.SM4_ECB = 'SM4-ECB';
|
|
123
|
+
exports.SM4_CBC = 'SM4-CBC';
|
|
124
|
+
exports.SM4_CFB = 'SM4-CFB';
|
|
125
|
+
function cipherEncrypt(original, key, iv = '', method = exports.AES_256_ECB, output = 'base64') {
|
|
126
|
+
try {
|
|
127
|
+
if (typeof key === 'string' && key.length < 32) {
|
|
128
|
+
key = hashHmac('md5', key, 'MaiyunSalt');
|
|
129
|
+
}
|
|
130
|
+
const cip = crypto.createCipheriv(method, key, iv);
|
|
131
|
+
let r;
|
|
132
|
+
if (output !== 'buffer') {
|
|
133
|
+
if (typeof original === 'string') {
|
|
134
|
+
r = cip.update(original, 'utf8', 'base64');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
r = cip.update(original, undefined, 'base64');
|
|
138
|
+
}
|
|
139
|
+
r += cip.final('base64');
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
if (typeof original === 'string') {
|
|
143
|
+
r = cip.update(original, 'utf8');
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
r = cip.update(original);
|
|
147
|
+
}
|
|
148
|
+
r = Buffer.concat([r, cip.final()]);
|
|
149
|
+
}
|
|
150
|
+
return r;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function aesEncrypt(original, key, iv = '', method = exports.AES_256_ECB, output = 'base64') {
|
|
157
|
+
if (iv !== '') {
|
|
158
|
+
method = method === exports.AES_256_ECB ? exports.AES_256_CFB : method;
|
|
159
|
+
}
|
|
160
|
+
return cipherEncrypt(original, key, iv, method, output);
|
|
161
|
+
}
|
|
162
|
+
function sm4Encrypt(original, key, iv = '', method = exports.SM4_ECB, output = 'base64') {
|
|
163
|
+
if (iv !== '') {
|
|
164
|
+
method = method === exports.SM4_ECB ? exports.SM4_CFB : method;
|
|
165
|
+
}
|
|
166
|
+
return cipherEncrypt(original, key, iv, method, output);
|
|
167
|
+
}
|
|
168
|
+
function cipherDecrypt(encrypt, key, iv = '', method = exports.AES_256_ECB, output = 'binary') {
|
|
169
|
+
try {
|
|
170
|
+
if (typeof key === 'string' && key.length < 32) {
|
|
171
|
+
key = hashHmac('md5', key, 'MaiyunSalt');
|
|
172
|
+
}
|
|
173
|
+
const cip = crypto.createDecipheriv(method, key, iv);
|
|
174
|
+
let r;
|
|
175
|
+
if (output !== 'buffer') {
|
|
176
|
+
if (typeof encrypt === 'string') {
|
|
177
|
+
r = cip.update(encrypt, 'base64', 'binary');
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
r = cip.update(encrypt, undefined, 'binary');
|
|
181
|
+
}
|
|
182
|
+
r += cip.final('binary');
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
if (typeof encrypt === 'string') {
|
|
186
|
+
r = cip.update(encrypt, 'base64');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
r = cip.update(encrypt);
|
|
190
|
+
}
|
|
191
|
+
r = Buffer.concat([r, cip.final()]);
|
|
192
|
+
}
|
|
193
|
+
return r;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function aesDecrypt(encrypt, key, iv = '', method = exports.AES_256_ECB, output = 'binary') {
|
|
200
|
+
if (iv !== '') {
|
|
201
|
+
method = method === exports.AES_256_ECB ? exports.AES_256_CFB : method;
|
|
202
|
+
}
|
|
203
|
+
return cipherDecrypt(encrypt, key, iv, method, output);
|
|
204
|
+
}
|
|
205
|
+
function sm4Decrypt(encrypt, key, iv = '', method = exports.SM4_ECB, output = 'binary') {
|
|
206
|
+
if (iv !== '') {
|
|
207
|
+
method = method === exports.SM4_ECB ? exports.SM4_CFB : method;
|
|
208
|
+
}
|
|
209
|
+
return cipherDecrypt(encrypt, key, iv, method, output);
|
|
210
|
+
}
|
|
211
|
+
function hashHmac(algorithm, data, key, format = 'hex') {
|
|
212
|
+
const cry = key ? crypto.createHmac(algorithm, key) : crypto.createHash(algorithm);
|
|
213
|
+
cry.update(data);
|
|
214
|
+
if (format === 'buffer') {
|
|
215
|
+
return cry.digest();
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return cry.digest(format);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function hashHmacFile(algorithm, path, key, encoding = 'hex') {
|
|
222
|
+
return new Promise(function (resolve) {
|
|
223
|
+
const cry = key ? crypto.createHmac(algorithm, key) : crypto.createHash(algorithm);
|
|
224
|
+
const rs = fs.createReadStream(path);
|
|
225
|
+
rs.on('data', (chunk) => {
|
|
226
|
+
cry.update(chunk);
|
|
227
|
+
}).on('end', function () {
|
|
228
|
+
if (encoding === 'buffer') {
|
|
229
|
+
resolve(cry.digest());
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
resolve(cry.digest(encoding));
|
|
233
|
+
}
|
|
234
|
+
}).on('error', function () {
|
|
235
|
+
resolve(false);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function base64Encode(data) {
|
|
240
|
+
if (typeof data === 'string') {
|
|
241
|
+
return Buffer.from(data, 'utf8').toString('base64');
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
return Buffer.from(data).toString('base64');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function base64Decode(data, encoding = 'utf8') {
|
|
248
|
+
const buffer = Buffer.from(data, 'base64');
|
|
249
|
+
if (encoding === 'buffer') {
|
|
250
|
+
return buffer;
|
|
251
|
+
}
|
|
252
|
+
return buffer.toString('utf8');
|
|
253
|
+
}
|
|
254
|
+
function uuid(options) {
|
|
255
|
+
return crypto.randomUUID(options);
|
|
256
|
+
}
|
package/lib/crypto.ts
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
3
|
+
* Date: 2019-4-2 14:01:06
|
|
4
|
+
* Last: 2020-3-12 14:05:24, 2022-09-12 11:52:35, 2024-9-8 17:09:39, 2024-11-11 00:21:58
|
|
5
|
+
*/
|
|
6
|
+
import * as crypto from 'crypto';
|
|
7
|
+
// --- 库和定义 ---
|
|
8
|
+
import * as fs from '~/lib/fs';
|
|
9
|
+
|
|
10
|
+
// --- 非对称加密 ---
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* --- 创建非对称秘钥 ---
|
|
14
|
+
* @param type 如 rsa/ec
|
|
15
|
+
* @param options 参数
|
|
16
|
+
*/
|
|
17
|
+
export function generateKeyPair(type: string, options: {
|
|
18
|
+
'modulusLength'?: number;
|
|
19
|
+
'namedCurve'?: string;
|
|
20
|
+
'publicKeyEncoding'?: {
|
|
21
|
+
'type'?: 'pkcs1' | 'spki';
|
|
22
|
+
'format'?: 'pem' | 'der';
|
|
23
|
+
};
|
|
24
|
+
'privateKeyEncoding'?: {
|
|
25
|
+
'type'?: 'pkcs1' | 'pkcs8' | 'sec1';
|
|
26
|
+
'format'?: 'pem' | 'der';
|
|
27
|
+
};
|
|
28
|
+
} = {}): Promise<{
|
|
29
|
+
'public': string | Buffer;
|
|
30
|
+
'private': string | Buffer;
|
|
31
|
+
}> {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
if (options.modulusLength === undefined) {
|
|
34
|
+
options.modulusLength = 2048;
|
|
35
|
+
}
|
|
36
|
+
if (options.namedCurve !== undefined) {
|
|
37
|
+
options.namedCurve = options.namedCurve.toUpperCase();
|
|
38
|
+
}
|
|
39
|
+
if (options.publicKeyEncoding === undefined) {
|
|
40
|
+
options.publicKeyEncoding = {
|
|
41
|
+
'format': 'pem',
|
|
42
|
+
'type': 'spki'
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (options.publicKeyEncoding.type === undefined) {
|
|
46
|
+
options.publicKeyEncoding.type = 'spki';
|
|
47
|
+
}
|
|
48
|
+
if (options.publicKeyEncoding.format === undefined) {
|
|
49
|
+
options.publicKeyEncoding.format = 'pem';
|
|
50
|
+
}
|
|
51
|
+
if (options.privateKeyEncoding === undefined) {
|
|
52
|
+
options.privateKeyEncoding = {
|
|
53
|
+
'format': 'pem',
|
|
54
|
+
'type': 'pkcs8'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (options.privateKeyEncoding.type === undefined) {
|
|
58
|
+
options.privateKeyEncoding.type = 'pkcs8';
|
|
59
|
+
}
|
|
60
|
+
if (options.privateKeyEncoding.format === undefined) {
|
|
61
|
+
options.privateKeyEncoding.format = 'pem';
|
|
62
|
+
}
|
|
63
|
+
crypto.generateKeyPair(type as any, options as any, (
|
|
64
|
+
err: Error | null, publicKey: string | Buffer, privateKey: string | Buffer
|
|
65
|
+
) => {
|
|
66
|
+
resolve({
|
|
67
|
+
'private': privateKey,
|
|
68
|
+
'public': publicKey
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function sign(
|
|
75
|
+
data: crypto.BinaryLike, privateKey: crypto.KeyLike | crypto.SignKeyObjectInput | crypto.SignPrivateKeyInput | crypto.SignJsonWebKeyInput, format: 'hex' | 'base64' | 'binary', algorithm?: string
|
|
76
|
+
): string;
|
|
77
|
+
export function sign(
|
|
78
|
+
data: crypto.BinaryLike, privateKey: crypto.KeyLike | crypto.SignKeyObjectInput | crypto.SignPrivateKeyInput | crypto.SignJsonWebKeyInput, format?: 'buffer', algorithm?: string
|
|
79
|
+
): Buffer;
|
|
80
|
+
/**
|
|
81
|
+
* --- 非对称加签 ---
|
|
82
|
+
* @param data 数据
|
|
83
|
+
* @param privateKey 私钥
|
|
84
|
+
* @param format 输出格式
|
|
85
|
+
* @param algorithm 哈希方式
|
|
86
|
+
*/
|
|
87
|
+
export function sign(
|
|
88
|
+
data: crypto.BinaryLike, privateKey: crypto.KeyLike | crypto.SignKeyObjectInput | crypto.SignPrivateKeyInput | crypto.SignJsonWebKeyInput, format: 'hex' | 'base64' | 'buffer' | 'binary' = 'buffer', algorithm: string = 'sha256'
|
|
89
|
+
): string | Buffer {
|
|
90
|
+
const sign = crypto.createSign(algorithm);
|
|
91
|
+
sign.update(data);
|
|
92
|
+
return format === 'buffer' ? sign.sign(privateKey) : sign.sign(privateKey, format);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* --- 非对称验签 ---
|
|
97
|
+
* @param data 数据
|
|
98
|
+
* @param object 证书
|
|
99
|
+
* @param signature 签名
|
|
100
|
+
* @param algorithm 哈希方式
|
|
101
|
+
*/
|
|
102
|
+
export function verify(
|
|
103
|
+
data: crypto.BinaryLike, object: crypto.KeyLike | crypto.VerifyKeyObjectInput | crypto.VerifyPublicKeyInput | crypto.VerifyJsonWebKeyInput, signature: NodeJS.ArrayBufferView, algorithm: string = 'sha256'
|
|
104
|
+
): boolean {
|
|
105
|
+
const verify = crypto.createVerify(algorithm);
|
|
106
|
+
verify.update(data);
|
|
107
|
+
return verify.verify(object, signature);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* --- 非对称公钥加密 ---
|
|
112
|
+
* @param key 公钥
|
|
113
|
+
* @param buffer 数据
|
|
114
|
+
*/
|
|
115
|
+
export function publicEncrypt(
|
|
116
|
+
key: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, buffer: NodeJS.ArrayBufferView
|
|
117
|
+
): Buffer {
|
|
118
|
+
return crypto.publicEncrypt(key, buffer);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* --- 非对称私钥加密 ---
|
|
123
|
+
* @param key 私钥
|
|
124
|
+
* @param buffer 数据
|
|
125
|
+
*/
|
|
126
|
+
export function privateEncrypt(key: crypto.RsaPrivateKey | crypto.KeyLike, buffer: NodeJS.ArrayBufferView): Buffer {
|
|
127
|
+
return crypto.privateEncrypt(key, buffer);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* --- 非对称公钥解密 ---
|
|
132
|
+
* @param key 公钥
|
|
133
|
+
* @param buffer 数据
|
|
134
|
+
*/
|
|
135
|
+
export function publicDecrypt(
|
|
136
|
+
key: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, buffer: NodeJS.ArrayBufferView
|
|
137
|
+
): Buffer {
|
|
138
|
+
return crypto.publicDecrypt(key, buffer);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* --- 非对称私钥解密 ---
|
|
143
|
+
* @param key 私钥
|
|
144
|
+
* @param buffer 数据
|
|
145
|
+
*/
|
|
146
|
+
export function privateDecrypt(key: crypto.RsaPrivateKey | crypto.KeyLike, buffer: NodeJS.ArrayBufferView): Buffer {
|
|
147
|
+
return crypto.privateDecrypt(key, buffer);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// --- Cipher (AES/SM4...) 加/解密 ---
|
|
151
|
+
|
|
152
|
+
export const AES_256_ECB = 'AES-256-ECB'; // --- 如果未设置 iv,则默认这个 ---
|
|
153
|
+
export const AES_256_CBC = 'AES-256-CBC';
|
|
154
|
+
export const AES_256_CFB = 'AES-256-CFB'; // --- 一般用这个,设置 iv,自动就切换成了这个 ---
|
|
155
|
+
|
|
156
|
+
export const SM4_ECB = 'SM4-ECB'; // --- SM4 如果未设置 iv,则默认这个 ---
|
|
157
|
+
export const SM4_CBC = 'SM4-CBC';
|
|
158
|
+
export const SM4_CFB = 'SM4-CFB'; // --- SM4 一般用这个,设置 iv,自动就切换成了这个 ---
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* --- cipher 加密 ---
|
|
162
|
+
* @param original 原始字符串
|
|
163
|
+
* @param key 密钥 32 个英文字母和数字
|
|
164
|
+
* @param iv 向量 16 个英文字母和数字
|
|
165
|
+
* @param method 加密方法
|
|
166
|
+
*/
|
|
167
|
+
export function cipherEncrypt(original: string | Buffer, key: crypto.CipherKey, iv: string = '', method: string = AES_256_ECB, output: 'base64' | 'buffer' = 'base64'): string | Buffer | false {
|
|
168
|
+
try {
|
|
169
|
+
if (typeof key === 'string' && key.length < 32) {
|
|
170
|
+
key = hashHmac('md5', key, 'MaiyunSalt');
|
|
171
|
+
}
|
|
172
|
+
const cip = crypto.createCipheriv(method, key, iv);
|
|
173
|
+
let r: string | Buffer;
|
|
174
|
+
if (output !== 'buffer') {
|
|
175
|
+
if (typeof original === 'string') {
|
|
176
|
+
r = cip.update(original, 'utf8', 'base64');
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
r = cip.update(original, undefined, 'base64');
|
|
180
|
+
}
|
|
181
|
+
r += cip.final('base64');
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
if (typeof original === 'string') {
|
|
185
|
+
r = cip.update(original, 'utf8');
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
r = cip.update(original);
|
|
189
|
+
}
|
|
190
|
+
r = Buffer.concat([r, cip.final()]);
|
|
191
|
+
}
|
|
192
|
+
return r;
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function aesEncrypt(original: string | Buffer, key: crypto.CipherKey, iv: string, method: string, output: 'buffer'): Buffer | false;
|
|
200
|
+
export function aesEncrypt(original: string | Buffer, key: crypto.CipherKey, iv?: string, method?: string, output?: 'base64'): string | false;
|
|
201
|
+
/**
|
|
202
|
+
* --- AES 加密 ---
|
|
203
|
+
* @param original 原始字符串
|
|
204
|
+
* @param key 密钥 32 个英文字母和数字
|
|
205
|
+
* @param iv 向量 16 个英文字母和数字
|
|
206
|
+
* @param method 加密方法
|
|
207
|
+
*/
|
|
208
|
+
export function aesEncrypt(original: string | Buffer, key: crypto.CipherKey, iv: string = '', method: string = AES_256_ECB, output: 'base64' | 'buffer' = 'base64'): string | Buffer | false {
|
|
209
|
+
if (iv !== '') {
|
|
210
|
+
method = method === AES_256_ECB ? AES_256_CFB : method;
|
|
211
|
+
}
|
|
212
|
+
return cipherEncrypt(original, key, iv, method, output);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function sm4Encrypt(original: string | Buffer, key: crypto.CipherKey, iv: string, method: string, output: 'buffer'): Buffer | false;
|
|
216
|
+
export function sm4Encrypt(original: string | Buffer, key: crypto.CipherKey, iv?: string, method?: string, output?: 'base64'): string | false;
|
|
217
|
+
/**
|
|
218
|
+
* --- SM4 加密 ---
|
|
219
|
+
* @param original 原始字符串
|
|
220
|
+
* @param key 密钥 32 个英文字母和数字
|
|
221
|
+
* @param iv 向量 16 个英文字母和数字
|
|
222
|
+
* @param method 加密方法
|
|
223
|
+
*/
|
|
224
|
+
export function sm4Encrypt(original: string | Buffer, key: crypto.CipherKey, iv: string = '', method: string = SM4_ECB, output: 'base64' | 'buffer' = 'base64'): string | Buffer | false {
|
|
225
|
+
if (iv !== '') {
|
|
226
|
+
method = method === SM4_ECB ? SM4_CFB : method;
|
|
227
|
+
}
|
|
228
|
+
return cipherEncrypt(original, key, iv, method, output);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* --- cipher 解密 ---
|
|
233
|
+
* @param encrypt 需解密的字符串
|
|
234
|
+
* @param key 密钥 32 个英文字母和数字
|
|
235
|
+
* @param iv 向量 16 个英文字母和数字
|
|
236
|
+
* @param method 加密方法
|
|
237
|
+
*/
|
|
238
|
+
export function cipherDecrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv: string = '', method: string = AES_256_ECB, output: 'binary' | 'buffer' = 'binary'): string | Buffer | false {
|
|
239
|
+
try {
|
|
240
|
+
if (typeof key === 'string' && key.length < 32) {
|
|
241
|
+
key = hashHmac('md5', key, 'MaiyunSalt');
|
|
242
|
+
}
|
|
243
|
+
const cip = crypto.createDecipheriv(method, key, iv);
|
|
244
|
+
let r: string | Buffer;
|
|
245
|
+
if (output !== 'buffer') {
|
|
246
|
+
if (typeof encrypt === 'string') {
|
|
247
|
+
r = cip.update(encrypt, 'base64', 'binary');
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
r = cip.update(encrypt, undefined, 'binary');
|
|
251
|
+
}
|
|
252
|
+
r += cip.final('binary');
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
if (typeof encrypt === 'string') {
|
|
256
|
+
r = cip.update(encrypt, 'base64');
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
r = cip.update(encrypt);
|
|
260
|
+
}
|
|
261
|
+
r = Buffer.concat([r, cip.final()]);
|
|
262
|
+
}
|
|
263
|
+
return r;
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function aesDecrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv: string, method: string, output: 'buffer'): Buffer | false;
|
|
271
|
+
export function aesDecrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv?: string, method?: string, output?: 'binary'): string | false;
|
|
272
|
+
/**
|
|
273
|
+
* --- AES 解密 ---
|
|
274
|
+
* @param encrypt 需解密的字符串
|
|
275
|
+
* @param key 密钥 32 个英文字母和数字
|
|
276
|
+
* @param iv 向量 16 个英文字母和数字
|
|
277
|
+
* @param method 加密方法
|
|
278
|
+
*/
|
|
279
|
+
export function aesDecrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv: string = '', method: string = AES_256_ECB, output: 'binary' | 'buffer' = 'binary'): string | Buffer | false {
|
|
280
|
+
if (iv !== '') {
|
|
281
|
+
method = method === AES_256_ECB ? AES_256_CFB : method;
|
|
282
|
+
}
|
|
283
|
+
return cipherDecrypt(encrypt, key, iv, method, output);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function sm4Decrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv: string, method: string, output: 'buffer'): Buffer | false;
|
|
287
|
+
export function sm4Decrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv?: string, method?: string, output?: 'binary'): string | false;
|
|
288
|
+
/**
|
|
289
|
+
* --- SM4 解密 ---
|
|
290
|
+
* @param encrypt 需解密的字符串
|
|
291
|
+
* @param key 密钥 32 个英文字母和数字
|
|
292
|
+
* @param iv 向量 16 个英文字母和数字
|
|
293
|
+
* @param method 加密方法
|
|
294
|
+
*/
|
|
295
|
+
export function sm4Decrypt(encrypt: string | Buffer, key: crypto.CipherKey, iv: string = '', method: string = SM4_ECB, output: 'binary' | 'buffer' = 'binary'): string | Buffer | false {
|
|
296
|
+
if (iv !== '') {
|
|
297
|
+
method = method === SM4_ECB ? SM4_CFB : method;
|
|
298
|
+
}
|
|
299
|
+
return cipherDecrypt(encrypt, key, iv, method, output);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// --- 以下是 Mutton: false, Kebab: true ---
|
|
303
|
+
|
|
304
|
+
export function hashHmac(algorithm: string, data: Buffer | string, key?: crypto.CipherKey, format?: 'hex' | 'base64'): string;
|
|
305
|
+
export function hashHmac(algorithm: string, data: Buffer | string, key: crypto.CipherKey | undefined, format: 'buffer'): Buffer;
|
|
306
|
+
/**
|
|
307
|
+
* --- hash 或 hmac 加密 ---
|
|
308
|
+
* @param algorithm 哈希方式
|
|
309
|
+
* @param data 源数据
|
|
310
|
+
* @param key 设置则采用 hmac 加密
|
|
311
|
+
*/
|
|
312
|
+
export function hashHmac(algorithm: string, data: Buffer | string, key?: crypto.CipherKey, format: 'hex' | 'base64' | 'buffer' = 'hex'): string | Buffer {
|
|
313
|
+
const cry = key ? crypto.createHmac(algorithm, key) : crypto.createHash(algorithm);
|
|
314
|
+
cry.update(data);
|
|
315
|
+
if (format === 'buffer') {
|
|
316
|
+
return cry.digest();
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
return cry.digest(format);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export function hashHmacFile(algorithm: string, path: string, key?: crypto.CipherKey, encoding?: 'hex' | 'base64' | 'base64url'): Promise<string | false>;
|
|
324
|
+
export function hashHmacFile(algorithm: string, path: string, key: crypto.CipherKey, encoding: 'buffer'): Promise<Buffer | false>;
|
|
325
|
+
/**
|
|
326
|
+
* --- hash 或 hmac 加密文件 ---
|
|
327
|
+
* @param algorithm 加密方式,如 md5、sha256、sm3 等
|
|
328
|
+
* @param path 文件路径
|
|
329
|
+
* @param key 设置则采用 hmac 加密
|
|
330
|
+
*/
|
|
331
|
+
export function hashHmacFile(algorithm: string, path: string, key?: crypto.CipherKey, encoding: 'hex' | 'base64' | 'base64url' | 'buffer' = 'hex'): Promise<string | Buffer | false> {
|
|
332
|
+
return new Promise(function(resolve) {
|
|
333
|
+
const cry = key ? crypto.createHmac(algorithm, key) : crypto.createHash(algorithm);
|
|
334
|
+
const rs = fs.createReadStream(path);
|
|
335
|
+
rs.on('data', (chunk) => {
|
|
336
|
+
cry.update(chunk);
|
|
337
|
+
}).on('end', function() {
|
|
338
|
+
if (encoding === 'buffer') {
|
|
339
|
+
resolve(cry.digest());
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
resolve(cry.digest(encoding));
|
|
343
|
+
}
|
|
344
|
+
}).on('error', function() {
|
|
345
|
+
resolve(false);
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* --- base64 编码 ---
|
|
352
|
+
* @param data 字符串或 Buffer
|
|
353
|
+
*/
|
|
354
|
+
export function base64Encode(data: string | Buffer): string {
|
|
355
|
+
if (typeof data === 'string') {
|
|
356
|
+
return Buffer.from(data, 'utf8').toString('base64');
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
return Buffer.from(data).toString('base64');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* --- base64 解码 ---
|
|
365
|
+
* @param data base64 编码的字符串
|
|
366
|
+
* @param encoding 指定解出 Buffer 还是 string ---
|
|
367
|
+
*/
|
|
368
|
+
export function base64Decode(data: string, encoding: 'buffer'): Buffer;
|
|
369
|
+
export function base64Decode(data: string, encoding?: 'utf8'): string;
|
|
370
|
+
export function base64Decode(data: string, encoding: 'utf8' | 'buffer' = 'utf8'): Buffer | string {
|
|
371
|
+
const buffer = Buffer.from(data, 'base64');
|
|
372
|
+
if (encoding === 'buffer') {
|
|
373
|
+
return buffer;
|
|
374
|
+
}
|
|
375
|
+
return buffer.toString('utf8');
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* --- 生成 uuid ---
|
|
380
|
+
* @param options 选项
|
|
381
|
+
*/
|
|
382
|
+
export function uuid(options?: crypto.RandomUUIDOptions): string {
|
|
383
|
+
return crypto.randomUUID(options);
|
|
384
|
+
}
|