@tmsfe/tms-core 0.0.159 → 0.0.161
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/package.json +1 -1
- package/src/encrypt/encrypt-util.ts +60 -47
- package/src/encrypt/md5.js +2 -0
- package/src/md5.js +0 -20
- package/src/navbarUtils.js +1 -1
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 暴露出来的工具函数封装原则:不可以向外throw错误,返回执行结果统一格式:{ success: boolean, msg: string, res: any }
|
|
4
4
|
* https://iwiki.woa.com/p/4013041987#1.-RSA+AES-%E5%88%87%E6%8D%A2-Curve25519+XSalsa20%EF%BC%9A
|
|
5
5
|
*/
|
|
6
|
-
import md5 from '
|
|
6
|
+
import md5 from './md5';
|
|
7
7
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
8
8
|
const ecc = require('./nacl.min.js');
|
|
9
9
|
const base64Util = require('./nacl-util.min.js');
|
|
@@ -100,7 +100,7 @@ const eccUtil = {
|
|
|
100
100
|
if (!wx.$_publicKey || forceRefresh) {
|
|
101
101
|
// eslint-disable-next-line
|
|
102
102
|
eccUtil._refreshPromise = new Promise(async (resolve) => {
|
|
103
|
-
const url = `${baseUtil.getSinanHost()}/basic/crypto/
|
|
103
|
+
const url = `${baseUtil.getSinanHost()}/basic/crypto/lastkey2`;
|
|
104
104
|
const data = await composeParamsFunc({});
|
|
105
105
|
wx.request({
|
|
106
106
|
url,
|
|
@@ -193,7 +193,7 @@ const eccUtil = {
|
|
|
193
193
|
}, [])
|
|
194
194
|
.join('&');
|
|
195
195
|
// 2. md5
|
|
196
|
-
const md5Str = md5(str
|
|
196
|
+
const md5Str = md5(str);
|
|
197
197
|
const nonce = ecc.randomBytes(ecc.box.nonceLength);
|
|
198
198
|
const encrypted = ecc.box.after(md5Str, nonce, sharedByte);
|
|
199
199
|
const combined = new Uint8Array(nonce.length + encrypted.length);
|
|
@@ -203,34 +203,43 @@ const eccUtil = {
|
|
|
203
203
|
},
|
|
204
204
|
// 验证服务端加密签名
|
|
205
205
|
verifyServerCryptoSign: (traceId: string, resHeader = {}): boolean => {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
206
|
+
try {
|
|
207
|
+
const formatHeader = baseUtil.formatHeader(resHeader);
|
|
208
|
+
const signStr = formatHeader['x-crypto-sign'];
|
|
209
|
+
if (!signStr) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const obj = {
|
|
213
|
+
'x-encrypt-key': formatHeader['x-encrypt-key'],
|
|
214
|
+
'x-encrypt-response': formatHeader['x-encrypt-response'],
|
|
215
|
+
'x-response-header-name': formatHeader['x-response-header-name'],
|
|
216
|
+
'x-encrypted-headers': formatHeader['x-encrypted-headers'],
|
|
217
|
+
'x-crypto-enable': formatHeader['x-crypto-enable'],
|
|
218
|
+
'content-type': formatHeader['content-type'],
|
|
219
|
+
'x-gateway-code': formatHeader['x-gateway-code'],
|
|
220
|
+
'x-crypto-pub-id': formatHeader['x-crypto-pub-id'],
|
|
221
|
+
'x-crypto-pub-key': formatHeader['x-crypto-pub-key'],
|
|
222
|
+
'x-crypto-pub-exp': formatHeader['x-crypto-pub-exp'],
|
|
223
|
+
'x-crypto-path': formatHeader['x-crypto-path'],
|
|
224
|
+
'x-trace-id': traceId,
|
|
225
|
+
};
|
|
226
|
+
const msg = baseUtil.decUrl(signStr);
|
|
227
|
+
const decrypted = ecc.sign.open(msg, eccUtil._getSignSharedByte());
|
|
228
|
+
const str = Object.keys(obj).filter(item => obj[item])
|
|
229
|
+
.sort()
|
|
230
|
+
.reduce((pre, cur) => {
|
|
231
|
+
pre.push(`${cur}=${obj[cur]}`);
|
|
232
|
+
return pre;
|
|
233
|
+
}, [])
|
|
234
|
+
.join('&');
|
|
235
|
+
const preHashArr = md5(str);
|
|
236
|
+
const verified = preHashArr.length === decrypted.length && preHashArr.every((v, i) => v === decrypted[i]);
|
|
237
|
+
return verified;
|
|
238
|
+
} catch (e) {
|
|
239
|
+
console.error('verifyServerCryptoSign error', e);
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
234
243
|
},
|
|
235
244
|
/* eslint-enable complexity */
|
|
236
245
|
execEncrypt: (input: string, ignoreNull = false): BaseResp<{
|
|
@@ -272,6 +281,9 @@ const eccUtil = {
|
|
|
272
281
|
return new baseUtil.BaseRespFac('', false, `execDecrypt失败:${JSON.stringify(err)}`);;
|
|
273
282
|
}
|
|
274
283
|
},
|
|
284
|
+
checkCryptoOpen: (): boolean => {
|
|
285
|
+
return !!eccUtil._privateKeyInfo;
|
|
286
|
+
},
|
|
275
287
|
closeCrypto: () => {
|
|
276
288
|
eccUtil._privateKeyInfo = null;
|
|
277
289
|
eccUtil._updateGlobalPublicKeyInfo(true);
|
|
@@ -317,11 +329,11 @@ const cryptRuleUtil = {
|
|
|
317
329
|
},
|
|
318
330
|
// 不参与加密的请求路径规则: { 允许的域名: 不需要加密的path }
|
|
319
331
|
_encryptPathRule: {
|
|
320
|
-
'tim.map.qq.com': ['^/user/login', '^/api/getClientConfigs', '^/basic/crypto/
|
|
332
|
+
'tim.map.qq.com': ['^/user/login', '^/api/getClientConfigs', '^/basic/crypto/lastkey2'],
|
|
321
333
|
'tim.sparta.html5.qq.com': [
|
|
322
334
|
'^/user/login',
|
|
323
335
|
'^/cnabroad', '^~/ReChargeCard/', '^/gasolinerecharge/v2/', '^/gasolinerecharge/rechargecard/',
|
|
324
|
-
'^/tde', '^/basic/crypto/
|
|
336
|
+
'^/tde', '^/basic/crypto/lastkey2',
|
|
325
337
|
],
|
|
326
338
|
},
|
|
327
339
|
isHostValid: (url) => {
|
|
@@ -503,23 +515,24 @@ const dealEncryptionSwitch = async (path: string, traceId: string, resHeader): P
|
|
|
503
515
|
}
|
|
504
516
|
dealEncryptionSwitching = true;
|
|
505
517
|
const formatHeader = baseUtil.formatHeader(resHeader);
|
|
506
|
-
|
|
507
|
-
|
|
518
|
+
// 加密关闭或者`login接口和lastkey接口`,都需要先执行验签
|
|
519
|
+
const cryptoDisabled = formatHeader['x-crypto-enable'] === '0';
|
|
520
|
+
const specialPath = [
|
|
521
|
+
`${baseUtil.getSinanHost()}/user/login`,
|
|
522
|
+
`${baseUtil.getSinanHost()}/basic/crypto/lastkey2`,
|
|
523
|
+
].indexOf(path) > -1;
|
|
524
|
+
if ((eccUtil.checkCryptoOpen() && cryptoDisabled) || specialPath ) {
|
|
508
525
|
const verified = eccUtil.verifyServerCryptoSign(traceId, formatHeader);
|
|
509
|
-
if (verified) {
|
|
510
|
-
|
|
526
|
+
if (!verified) {
|
|
527
|
+
// 验签失败,表示响应被篡改
|
|
528
|
+
dealEncryptionSwitching = false;
|
|
529
|
+
return false;
|
|
511
530
|
}
|
|
531
|
+
}
|
|
532
|
+
if (cryptoDisabled) {
|
|
533
|
+
eccUtil.closeCrypto();
|
|
512
534
|
} else if (formatHeader['x-crypto-enable'] === '1') {
|
|
513
|
-
if (
|
|
514
|
-
`${baseUtil.getSinanHost()}/user/login`,
|
|
515
|
-
`${baseUtil.getSinanHost()}/basic/crypto/lastkey`,
|
|
516
|
-
].indexOf(path) > -1) {
|
|
517
|
-
const verified = eccUtil.verifyServerCryptoSign(traceId, formatHeader);
|
|
518
|
-
if (!verified) {
|
|
519
|
-
// 验签失败,表示请求被篡改
|
|
520
|
-
dealEncryptionSwitching = false;
|
|
521
|
-
return false;
|
|
522
|
-
}
|
|
535
|
+
if (specialPath) {
|
|
523
536
|
eccUtil._updateGlobalPublicKeyInfo(false, formatHeader);
|
|
524
537
|
}
|
|
525
538
|
await eccUtil.openCrypto();
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
function safeAdd(x,y){const lsw=(x&0xffff)+(y&0xffff);const msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xffff)}function bitRotateLeft(num,cnt){return(num<<cnt)|(num>>>(32-cnt))}function md5cmn(q,a,b,x,s,t){return safeAdd(bitRotateLeft(safeAdd(safeAdd(a,q),safeAdd(x,t)),s),b)}function md5ff(a,b,c,d,x,s,t){return md5cmn((b&c)|(~b&d),a,b,x,s,t)}function md5gg(a,b,c,d,x,s,t){return md5cmn((b&d)|(c&~d),a,b,x,s,t)}function md5hh(a,b,c,d,x,s,t){return md5cmn(b^c^d,a,b,x,s,t)}function md5ii(a,b,c,d,x,s,t){return md5cmn(c^(b|~d),a,b,x,s,t)}function binlMD5(x,len){x[len>>5]|=0x80<<len%32;x[(((len+64)>>>9)<<4)+14]=len;let a=1732584193;let b=-271733879;let c=-1732584194;let d=271733878;for(let i=0;i<x.length;i+=16){const olda=a;const oldb=b;const oldc=c;const oldd=d;a=md5ff(a,b,c,d,x[i],7,-680876936);d=md5ff(d,a,b,c,x[i+1],12,-389564586);c=md5ff(c,d,a,b,x[i+2],17,606105819);b=md5ff(b,c,d,a,x[i+3],22,-1044525330);a=md5ff(a,b,c,d,x[i+4],7,-176418897);d=md5ff(d,a,b,c,x[i+5],12,1200080426);c=md5ff(c,d,a,b,x[i+6],17,-1473231341);b=md5ff(b,c,d,a,x[i+7],22,-45705983);a=md5ff(a,b,c,d,x[i+8],7,1770035416);d=md5ff(d,a,b,c,x[i+9],12,-1958414417);c=md5ff(c,d,a,b,x[i+10],17,-42063);b=md5ff(b,c,d,a,x[i+11],22,-1990404162);a=md5ff(a,b,c,d,x[i+12],7,1804603682);d=md5ff(d,a,b,c,x[i+13],12,-40341101);c=md5ff(c,d,a,b,x[i+14],17,-1502002290);b=md5ff(b,c,d,a,x[i+15],22,1236535329);a=md5gg(a,b,c,d,x[i+1],5,-165796510);d=md5gg(d,a,b,c,x[i+6],9,-1069501632);c=md5gg(c,d,a,b,x[i+11],14,643717713);b=md5gg(b,c,d,a,x[i],20,-373897302);a=md5gg(a,b,c,d,x[i+5],5,-701558691);d=md5gg(d,a,b,c,x[i+10],9,38016083);c=md5gg(c,d,a,b,x[i+15],14,-660478335);b=md5gg(b,c,d,a,x[i+4],20,-405537848);a=md5gg(a,b,c,d,x[i+9],5,568446438);d=md5gg(d,a,b,c,x[i+14],9,-1019803690);c=md5gg(c,d,a,b,x[i+3],14,-187363961);b=md5gg(b,c,d,a,x[i+8],20,1163531501);a=md5gg(a,b,c,d,x[i+13],5,-1444681467);d=md5gg(d,a,b,c,x[i+2],9,-51403784);c=md5gg(c,d,a,b,x[i+7],14,1735328473);b=md5gg(b,c,d,a,x[i+12],20,-1926607734);a=md5hh(a,b,c,d,x[i+5],4,-378558);d=md5hh(d,a,b,c,x[i+8],11,-2022574463);c=md5hh(c,d,a,b,x[i+11],16,1839030562);b=md5hh(b,c,d,a,x[i+14],23,-35309556);a=md5hh(a,b,c,d,x[i+1],4,-1530992060);d=md5hh(d,a,b,c,x[i+4],11,1272893353);c=md5hh(c,d,a,b,x[i+7],16,-155497632);b=md5hh(b,c,d,a,x[i+10],23,-1094730640);a=md5hh(a,b,c,d,x[i+13],4,681279174);d=md5hh(d,a,b,c,x[i],11,-358537222);c=md5hh(c,d,a,b,x[i+3],16,-722521979);b=md5hh(b,c,d,a,x[i+6],23,76029189);a=md5hh(a,b,c,d,x[i+9],4,-640364487);d=md5hh(d,a,b,c,x[i+12],11,-421815835);c=md5hh(c,d,a,b,x[i+15],16,530742520);b=md5hh(b,c,d,a,x[i+2],23,-995338651);a=md5ii(a,b,c,d,x[i],6,-198630844);d=md5ii(d,a,b,c,x[i+7],10,1126891415);c=md5ii(c,d,a,b,x[i+14],15,-1416354905);b=md5ii(b,c,d,a,x[i+5],21,-57434055);a=md5ii(a,b,c,d,x[i+12],6,1700485571);d=md5ii(d,a,b,c,x[i+3],10,-1894986606);c=md5ii(c,d,a,b,x[i+10],15,-1051523);b=md5ii(b,c,d,a,x[i+1],21,-2054922799);a=md5ii(a,b,c,d,x[i+8],6,1873313359);d=md5ii(d,a,b,c,x[i+15],10,-30611744);c=md5ii(c,d,a,b,x[i+6],15,-1560198380);b=md5ii(b,c,d,a,x[i+13],21,1309151649);a=md5ii(a,b,c,d,x[i+4],6,-145523070);d=md5ii(d,a,b,c,x[i+11],10,-1120210379);c=md5ii(c,d,a,b,x[i+2],15,718787259);b=md5ii(b,c,d,a,x[i+9],21,-343485551);a=safeAdd(a,olda);b=safeAdd(b,oldb);c=safeAdd(c,oldc);d=safeAdd(d,oldd)}return[a,b,c,d]}function binl2rstr(input){let output='';const length32=input.length*32;for(let i=0;i<length32;i+=8){output+=String.fromCharCode((input[i>>5]>>>i%32)&0xff)}return output}function rstr2binl(input){const output=[];output[(input.length>>2)-1]=undefined;for(let i=0;i<output.length;i+=1){output[i]=0}const length8=input.length*8;for(let i=0;i<length8;i+=8){output[i>>5]|=(input.charCodeAt(i/8)&0xff)<<i%32}return output}function rstrMD5(s){return binl2rstr(binlMD5(rstr2binl(s),s.length*8))}function str2rstrUTF8(input){return unescape(encodeURIComponent(input))}function rawMD5(s){return rstrMD5(str2rstrUTF8(s))}function rstr2uint8array(input){const output=new Uint8Array(input.length);for(let i=0;i<input.length;i++){output[i]=input.charCodeAt(i)}return output}function md5(string){return rstr2uint8array(rawMD5(string))}export default md5;
|
package/src/md5.js
CHANGED
|
@@ -349,20 +349,6 @@ function hexHMACMD5(k, d) {
|
|
|
349
349
|
return rstr2hex(rawHMACMD5(k, d));
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
-
/**
|
|
353
|
-
* 将原始二进制字符串转换为 Uint8Array
|
|
354
|
-
*
|
|
355
|
-
* @param {string} input 原始的 MD5 二进制字符串
|
|
356
|
-
* @returns {Uint8Array} Uint8Array 格式的 MD5 哈希值
|
|
357
|
-
*/
|
|
358
|
-
function rstr2uint8array(input) {
|
|
359
|
-
const output = new Uint8Array(input.length);
|
|
360
|
-
for (let i = 0; i < input.length; i++) {
|
|
361
|
-
output[i] = input.charCodeAt(i);
|
|
362
|
-
}
|
|
363
|
-
return output;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
352
|
/**
|
|
367
353
|
* Calculates MD5 value for a given string.
|
|
368
354
|
* If a key is provided, calculates the HMAC-MD5 value.
|
|
@@ -378,17 +364,11 @@ function md5(string, key, raw) {
|
|
|
378
364
|
if (!raw) {
|
|
379
365
|
return hexMD5(string);
|
|
380
366
|
}
|
|
381
|
-
if (raw === 'unit8array') {
|
|
382
|
-
return rstr2uint8array(rawMD5(string));
|
|
383
|
-
}
|
|
384
367
|
return rawMD5(string);
|
|
385
368
|
}
|
|
386
369
|
if (!raw) {
|
|
387
370
|
return hexHMACMD5(key, string);
|
|
388
371
|
}
|
|
389
|
-
if (raw === 'unit8array') {
|
|
390
|
-
return rstr2uint8array(rawHMACMD5(key, string));
|
|
391
|
-
}
|
|
392
372
|
return rawHMACMD5(key, string);
|
|
393
373
|
}
|
|
394
374
|
|
package/src/navbarUtils.js
CHANGED
|
@@ -151,7 +151,7 @@ const getNavBarConfigData = () => { // eslint-disable-line require-jsdoc
|
|
|
151
151
|
statusBarHeight = isIOS ? StatusBarHeightOnIOS : StatusBarHeightOnAndroid;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
const enable = compareVersion(version, '7.0.0') >= 0 || brand === 'devtools'; // 微信版本是否支持自定义顶栏,不支持时自动隐藏
|
|
154
|
+
const enable = compareVersion(version, '7.0.0') >= 0 || brand === 'devtools' || platform === 'ohos'; // 微信版本是否支持自定义顶栏,不支持时自动隐藏
|
|
155
155
|
const enterOptions = getEnterOptions();
|
|
156
156
|
if (enable) {
|
|
157
157
|
return { enable, ...calculateNavBarLayout(isIOS, statusBarHeight, enterOptions.apiCategory) };
|