@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmsfe/tms-core",
3
- "version": "0.0.159",
3
+ "version": "0.0.161",
4
4
  "description": "tms运行时框架",
5
5
  "repository": {
6
6
  "type": "git",
@@ -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 '../md5';
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/lastkey`;
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, '', 'unit8array');
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
- const formatHeader = baseUtil.formatHeader(resHeader);
207
- const signStr = formatHeader['x-crypto-sign'];
208
- const obj = {
209
- 'x-encrypt-key': formatHeader['x-encrypt-key'],
210
- 'x-encrypt-response': formatHeader['x-encrypt-response'],
211
- 'x-response-header-name': formatHeader['x-response-header-name'],
212
- 'x-encrypted-headers': formatHeader['x-encrypted-headers'],
213
- 'x-crypto-enable': formatHeader['x-crypto-enable'],
214
- 'content-type': formatHeader['content-type'],
215
- 'x-gateway-code': formatHeader['x-gateway-code'],
216
- 'x-crypto-pub-id': formatHeader['x-crypto-pub-id'],
217
- 'x-crypto-pub-key': formatHeader['x-crypto-pub-key'],
218
- 'x-crypto-pub-exp': formatHeader['x-crypto-pub-exp'],
219
- 'x-crypto-path': formatHeader['x-crypto-path'],
220
- 'x-trace-id': traceId,
221
- };
222
- const msg = baseUtil.decUrl(signStr);
223
- const decrypted = ecc.sign.open(msg, eccUtil._getSignSharedByte());
224
- const str = Object.keys(obj).filter(item => obj[item])
225
- .sort()
226
- .reduce((pre, cur) => {
227
- pre.push(`${cur}=${obj[cur]}`);
228
- return pre;
229
- }, [])
230
- .join('&');
231
- const preHashArr = md5(str, '', 'unit8array');
232
- const verified = preHashArr.length === decrypted.length && preHashArr.every((v, i) => v === decrypted[i]);
233
- return verified;
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/lastkey'],
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/lastkey',
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
- if (formatHeader['x-crypto-enable'] === '0') {
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
- eccUtil.closeCrypto();
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
 
@@ -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) };