1849 lines
49 KiB
JavaScript
1849 lines
49 KiB
JavaScript
module.exports =
|
||
/******/ (function(modules) { // webpackBootstrap
|
||
/******/ // The module cache
|
||
/******/ var installedModules = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/
|
||
/******/ // Check if module is in cache
|
||
/******/ if(installedModules[moduleId]) {
|
||
/******/ return installedModules[moduleId].exports;
|
||
/******/ }
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = installedModules[moduleId] = {
|
||
/******/ i: moduleId,
|
||
/******/ l: false,
|
||
/******/ exports: {}
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.l = true;
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = modules;
|
||
/******/
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = installedModules;
|
||
/******/
|
||
/******/ // define getter function for harmony exports
|
||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||
/******/ }
|
||
/******/ };
|
||
/******/
|
||
/******/ // define __esModule on exports
|
||
/******/ __webpack_require__.r = function(exports) {
|
||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||
/******/ }
|
||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||
/******/ };
|
||
/******/
|
||
/******/ // create a fake namespace object
|
||
/******/ // mode & 1: value is a module id, require it
|
||
/******/ // mode & 2: merge all properties of value into the ns
|
||
/******/ // mode & 4: return value when already ns object
|
||
/******/ // mode & 8|1: behave like require
|
||
/******/ __webpack_require__.t = function(value, mode) {
|
||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||
/******/ if(mode & 8) return value;
|
||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||
/******/ var ns = Object.create(null);
|
||
/******/ __webpack_require__.r(ns);
|
||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||
/******/ return ns;
|
||
/******/ };
|
||
/******/
|
||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||
/******/ __webpack_require__.n = function(module) {
|
||
/******/ var getter = module && module.__esModule ?
|
||
/******/ function getDefault() { return module['default']; } :
|
||
/******/ function getModuleExports() { return module; };
|
||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||
/******/ return getter;
|
||
/******/ };
|
||
/******/
|
||
/******/ // Object.prototype.hasOwnProperty.call
|
||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||
/******/
|
||
/******/ // __webpack_public_path__
|
||
/******/ __webpack_require__.p = "";
|
||
/******/
|
||
/******/
|
||
/******/ // Load entry module and return exports
|
||
/******/ return __webpack_require__(__webpack_require__.s = 2);
|
||
/******/ })
|
||
/************************************************************************/
|
||
/******/ ([
|
||
/* 0 */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = require("jsbn");
|
||
|
||
/***/ }),
|
||
/* 1 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
/**
|
||
* 循环左移
|
||
*/
|
||
function rotl(x, n) {
|
||
var result = [];
|
||
var a = ~~(n / 8); // 偏移 a 字节
|
||
var b = n % 8; // 偏移 b 位
|
||
for (var i = 0, len = x.length; i < len; i++) {
|
||
// current << b + (current + 1) >>> (8 - b)
|
||
result[i] = (x[(i + a) % len] << b & 0xff) + (x[(i + a + 1) % len] >>> 8 - b & 0xff);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 二进制异或运算
|
||
*/
|
||
function xor(x, y) {
|
||
var result = [];
|
||
for (var i = x.length - 1; i >= 0; i--) {
|
||
result[i] = (x[i] ^ y[i]) & 0xff;
|
||
}return result;
|
||
}
|
||
|
||
/**
|
||
* 二进制与运算
|
||
*/
|
||
function and(x, y) {
|
||
var result = [];
|
||
for (var i = x.length - 1; i >= 0; i--) {
|
||
result[i] = x[i] & y[i] & 0xff;
|
||
}return result;
|
||
}
|
||
|
||
/**
|
||
* 二进制或运算
|
||
*/
|
||
function or(x, y) {
|
||
var result = [];
|
||
for (var i = x.length - 1; i >= 0; i--) {
|
||
result[i] = (x[i] | y[i]) & 0xff;
|
||
}return result;
|
||
}
|
||
|
||
/**
|
||
* 二进制与运算
|
||
*/
|
||
function add(x, y) {
|
||
var result = [];
|
||
var temp = 0;
|
||
for (var i = x.length - 1; i >= 0; i--) {
|
||
var sum = x[i] + y[i] + temp;
|
||
if (sum > 0xff) {
|
||
temp = 1;
|
||
result[i] = sum & 0xff;
|
||
} else {
|
||
temp = 0;
|
||
result[i] = sum & 0xff;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 二进制非运算
|
||
*/
|
||
function not(x) {
|
||
var result = [];
|
||
for (var i = x.length - 1; i >= 0; i--) {
|
||
result[i] = ~x[i] & 0xff;
|
||
}return result;
|
||
}
|
||
|
||
/**
|
||
* 压缩函数中的置换函数 P1(X) = X xor (X <<< 9) xor (X <<< 17)
|
||
*/
|
||
function P0(X) {
|
||
return xor(xor(X, rotl(X, 9)), rotl(X, 17));
|
||
}
|
||
|
||
/**
|
||
* 消息扩展中的置换函数 P1(X) = X xor (X <<< 15) xor (X <<< 23)
|
||
*/
|
||
function P1(X) {
|
||
return xor(xor(X, rotl(X, 15)), rotl(X, 23));
|
||
}
|
||
|
||
/**
|
||
* 布尔函数 FF
|
||
*/
|
||
function FF(X, Y, Z, j) {
|
||
return j >= 0 && j <= 15 ? xor(xor(X, Y), Z) : or(or(and(X, Y), and(X, Z)), and(Y, Z));
|
||
}
|
||
|
||
/**
|
||
* 布尔函数 GG
|
||
*/
|
||
function GG(X, Y, Z, j) {
|
||
return j >= 0 && j <= 15 ? xor(xor(X, Y), Z) : or(and(X, Y), and(not(X), Z));
|
||
}
|
||
|
||
/**
|
||
* 压缩函数
|
||
*/
|
||
function CF(V, Bi) {
|
||
// 消息扩展
|
||
var W = [];
|
||
var M = []; // W'
|
||
|
||
// 将消息分组B划分为 16 个字 W0, W1,……,W15
|
||
for (var i = 0; i < 16; i++) {
|
||
var start = i * 4;
|
||
W.push(Bi.slice(start, start + 4));
|
||
}
|
||
|
||
// W16 ~ W67:W[j] <- P1(W[j−16] xor W[j−9] xor (W[j−3] <<< 15)) xor (W[j−13] <<< 7) xor W[j−6]
|
||
for (var j = 16; j < 68; j++) {
|
||
W.push(xor(xor(P1(xor(xor(W[j - 16], W[j - 9]), rotl(W[j - 3], 15))), rotl(W[j - 13], 7)), W[j - 6]));
|
||
}
|
||
|
||
// W′0 ~ W′63:W′[j] = W[j] xor W[j+4]
|
||
for (var _j = 0; _j < 64; _j++) {
|
||
M.push(xor(W[_j], W[_j + 4]));
|
||
}
|
||
|
||
// 压缩
|
||
var T1 = [0x79, 0xcc, 0x45, 0x19];
|
||
var T2 = [0x7a, 0x87, 0x9d, 0x8a];
|
||
// 字寄存器
|
||
var A = V.slice(0, 4);
|
||
var B = V.slice(4, 8);
|
||
var C = V.slice(8, 12);
|
||
var D = V.slice(12, 16);
|
||
var E = V.slice(16, 20);
|
||
var F = V.slice(20, 24);
|
||
var G = V.slice(24, 28);
|
||
var H = V.slice(28, 32);
|
||
// 中间变量
|
||
var SS1 = void 0;
|
||
var SS2 = void 0;
|
||
var TT1 = void 0;
|
||
var TT2 = void 0;
|
||
for (var _j2 = 0; _j2 < 64; _j2++) {
|
||
var T = _j2 >= 0 && _j2 <= 15 ? T1 : T2;
|
||
SS1 = rotl(add(add(rotl(A, 12), E), rotl(T, _j2)), 7);
|
||
SS2 = xor(SS1, rotl(A, 12));
|
||
|
||
TT1 = add(add(add(FF(A, B, C, _j2), D), SS2), M[_j2]);
|
||
TT2 = add(add(add(GG(E, F, G, _j2), H), SS1), W[_j2]);
|
||
|
||
D = C;
|
||
C = rotl(B, 9);
|
||
B = A;
|
||
A = TT1;
|
||
H = G;
|
||
G = rotl(F, 19);
|
||
F = E;
|
||
E = P0(TT2);
|
||
}
|
||
|
||
return xor([].concat(A, B, C, D, E, F, G, H), V);
|
||
}
|
||
|
||
/**
|
||
* sm3 本体
|
||
*/
|
||
function sm3(array) {
|
||
// 填充
|
||
var len = array.length * 8;
|
||
|
||
// k 是满足 len + 1 + k = 448mod512 的最小的非负整数
|
||
var k = len % 512;
|
||
// 如果 448 <= (512 % len) < 512,需要多补充 (len % 448) 比特'0'以满足总比特长度为512的倍数
|
||
k = k >= 448 ? 512 - k % 448 - 1 : 448 - k - 1;
|
||
|
||
// 填充
|
||
var kArr = new Array((k - 7) / 8);
|
||
for (var i = 0, _len = kArr.length; i < _len; i++) {
|
||
kArr[i] = 0;
|
||
}var lenArr = [];
|
||
len = len.toString(2);
|
||
for (var _i = 7; _i >= 0; _i--) {
|
||
if (len.length > 8) {
|
||
var start = len.length - 8;
|
||
lenArr[_i] = parseInt(len.substr(start), 2);
|
||
len = len.substr(0, start);
|
||
} else if (len.length > 0) {
|
||
lenArr[_i] = parseInt(len, 2);
|
||
len = '';
|
||
} else {
|
||
lenArr[_i] = 0;
|
||
}
|
||
}
|
||
var m = [].concat(array, [0x80], kArr, lenArr);
|
||
|
||
// 迭代压缩
|
||
var n = m.length / 64;
|
||
var V = [0x73, 0x80, 0x16, 0x6f, 0x49, 0x14, 0xb2, 0xb9, 0x17, 0x24, 0x42, 0xd7, 0xda, 0x8a, 0x06, 0x00, 0xa9, 0x6f, 0x30, 0xbc, 0x16, 0x31, 0x38, 0xaa, 0xe3, 0x8d, 0xee, 0x4d, 0xb0, 0xfb, 0x0e, 0x4e];
|
||
for (var _i2 = 0; _i2 < n; _i2++) {
|
||
var _start = 64 * _i2;
|
||
var B = m.slice(_start, _start + 64);
|
||
V = CF(V, B);
|
||
}
|
||
return V;
|
||
}
|
||
|
||
/**
|
||
* hmac 实现
|
||
*/
|
||
var blockLen = 64;
|
||
var iPad = new Array(blockLen);
|
||
var oPad = new Array(blockLen);
|
||
for (var i = 0; i < blockLen; i++) {
|
||
iPad[i] = 0x36;
|
||
oPad[i] = 0x5c;
|
||
}
|
||
function hmac(input, key) {
|
||
// 密钥填充
|
||
if (key.length > blockLen) key = sm3(key);
|
||
while (key.length < blockLen) {
|
||
key.push(0);
|
||
}var iPadKey = xor(key, iPad);
|
||
var hash = iPadKey.concat(input);
|
||
hash = sm3(hash);
|
||
|
||
var oPadKey = xor(key, oPad);
|
||
hash = oPadKey.concat(hash);
|
||
hash = sm3(hash);
|
||
|
||
return hash;
|
||
}
|
||
|
||
module.exports = {
|
||
sm3: sm3,
|
||
hmac: hmac
|
||
};
|
||
|
||
/***/ }),
|
||
/* 2 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
module.exports = {
|
||
sm2: __webpack_require__(3),
|
||
sm3: __webpack_require__(7),
|
||
sm4: __webpack_require__(8)
|
||
};
|
||
|
||
/***/ }),
|
||
/* 3 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
/* eslint-disable no-use-before-define */
|
||
var _require = __webpack_require__(0),
|
||
BigInteger = _require.BigInteger;
|
||
|
||
var _require2 = __webpack_require__(4),
|
||
encodeDer = _require2.encodeDer,
|
||
decodeDer = _require2.decodeDer;
|
||
|
||
var _ = __webpack_require__(5);
|
||
var sm3 = __webpack_require__(1).sm3;
|
||
|
||
var _$generateEcparam = _.generateEcparam(),
|
||
G = _$generateEcparam.G,
|
||
curve = _$generateEcparam.curve,
|
||
n = _$generateEcparam.n;
|
||
|
||
var C1C2C3 = 0;
|
||
|
||
/**
|
||
* 加密
|
||
*/
|
||
function doEncrypt(msg, publicKey) {
|
||
var cipherMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
||
|
||
msg = typeof msg === 'string' ? _.hexToArray(_.utf8ToHex(msg)) : Array.prototype.slice.call(msg);
|
||
publicKey = _.getGlobalCurve().decodePointHex(publicKey); // 先将公钥转成点
|
||
|
||
var keypair = _.generateKeyPairHex();
|
||
var k = new BigInteger(keypair.privateKey, 16); // 随机数 k
|
||
|
||
// c1 = k * G
|
||
var c1 = keypair.publicKey;
|
||
if (c1.length > 128) c1 = c1.substr(c1.length - 128);
|
||
|
||
// (x2, y2) = k * publicKey
|
||
var p = publicKey.multiply(k);
|
||
var x2 = _.hexToArray(_.leftPad(p.getX().toBigInteger().toRadix(16), 64));
|
||
var y2 = _.hexToArray(_.leftPad(p.getY().toBigInteger().toRadix(16), 64));
|
||
|
||
// c3 = hash(x2 || msg || y2)
|
||
var c3 = _.arrayToHex(sm3([].concat(x2, msg, y2)));
|
||
|
||
var ct = 1;
|
||
var offset = 0;
|
||
var t = []; // 256 位
|
||
var z = [].concat(x2, y2);
|
||
var nextT = function nextT() {
|
||
// (1) Hai = hash(z || ct)
|
||
// (2) ct++
|
||
t = sm3([].concat(z, [ct >> 24 & 0x00ff, ct >> 16 & 0x00ff, ct >> 8 & 0x00ff, ct & 0x00ff]));
|
||
ct++;
|
||
offset = 0;
|
||
};
|
||
nextT(); // 先生成 Ha1
|
||
|
||
for (var i = 0, len = msg.length; i < len; i++) {
|
||
// t = Ha1 || Ha2 || Ha3 || Ha4
|
||
if (offset === t.length) nextT();
|
||
|
||
// c2 = msg ^ t
|
||
msg[i] ^= t[offset++] & 0xff;
|
||
}
|
||
var c2 = _.arrayToHex(msg);
|
||
|
||
return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2;
|
||
}
|
||
|
||
/**
|
||
* 解密
|
||
*/
|
||
function doDecrypt(encryptData, privateKey) {
|
||
var cipherMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
||
|
||
var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
|
||
_ref$output = _ref.output,
|
||
output = _ref$output === undefined ? 'string' : _ref$output;
|
||
|
||
privateKey = new BigInteger(privateKey, 16);
|
||
|
||
var c3 = encryptData.substr(128, 64);
|
||
var c2 = encryptData.substr(128 + 64);
|
||
|
||
if (cipherMode === C1C2C3) {
|
||
c3 = encryptData.substr(encryptData.length - 64);
|
||
c2 = encryptData.substr(128, encryptData.length - 128 - 64);
|
||
}
|
||
|
||
var msg = _.hexToArray(c2);
|
||
var c1 = _.getGlobalCurve().decodePointHex('04' + encryptData.substr(0, 128));
|
||
|
||
var p = c1.multiply(privateKey);
|
||
var x2 = _.hexToArray(_.leftPad(p.getX().toBigInteger().toRadix(16), 64));
|
||
var y2 = _.hexToArray(_.leftPad(p.getY().toBigInteger().toRadix(16), 64));
|
||
|
||
var ct = 1;
|
||
var offset = 0;
|
||
var t = []; // 256 位
|
||
var z = [].concat(x2, y2);
|
||
var nextT = function nextT() {
|
||
// (1) Hai = hash(z || ct)
|
||
// (2) ct++
|
||
t = sm3([].concat(z, [ct >> 24 & 0x00ff, ct >> 16 & 0x00ff, ct >> 8 & 0x00ff, ct & 0x00ff]));
|
||
ct++;
|
||
offset = 0;
|
||
};
|
||
nextT(); // 先生成 Ha1
|
||
|
||
for (var i = 0, len = msg.length; i < len; i++) {
|
||
// t = Ha1 || Ha2 || Ha3 || Ha4
|
||
if (offset === t.length) nextT();
|
||
|
||
// c2 = msg ^ t
|
||
msg[i] ^= t[offset++] & 0xff;
|
||
}
|
||
|
||
// c3 = hash(x2 || msg || y2)
|
||
var checkC3 = _.arrayToHex(sm3([].concat(x2, msg, y2)));
|
||
|
||
if (checkC3 === c3.toLowerCase()) {
|
||
return output === 'array' ? msg : _.arrayToUtf8(msg);
|
||
} else {
|
||
return output === 'array' ? [] : '';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 签名
|
||
*/
|
||
function doSignature(msg, privateKey) {
|
||
var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
|
||
pointPool = _ref2.pointPool,
|
||
der = _ref2.der,
|
||
hash = _ref2.hash,
|
||
publicKey = _ref2.publicKey,
|
||
userId = _ref2.userId;
|
||
|
||
var hashHex = typeof msg === 'string' ? _.utf8ToHex(msg) : _.arrayToHex(msg);
|
||
|
||
if (hash) {
|
||
// sm3杂凑
|
||
publicKey = publicKey || getPublicKeyFromPrivateKey(privateKey);
|
||
hashHex = getHash(hashHex, publicKey, userId);
|
||
}
|
||
|
||
var dA = new BigInteger(privateKey, 16);
|
||
var e = new BigInteger(hashHex, 16);
|
||
|
||
// k
|
||
var k = null;
|
||
var r = null;
|
||
var s = null;
|
||
|
||
do {
|
||
do {
|
||
var point = void 0;
|
||
if (pointPool && pointPool.length) {
|
||
point = pointPool.pop();
|
||
} else {
|
||
point = getPoint();
|
||
}
|
||
k = point.k;
|
||
|
||
// r = (e + x1) mod n
|
||
r = e.add(point.x1).mod(n);
|
||
} while (r.equals(BigInteger.ZERO) || r.add(k).equals(n));
|
||
|
||
// s = ((1 + dA)^-1 * (k - r * dA)) mod n
|
||
s = dA.add(BigInteger.ONE).modInverse(n).multiply(k.subtract(r.multiply(dA))).mod(n);
|
||
} while (s.equals(BigInteger.ZERO));
|
||
|
||
if (der) return encodeDer(r, s); // asn.1 der 编码
|
||
|
||
return _.leftPad(r.toString(16), 64) + _.leftPad(s.toString(16), 64);
|
||
}
|
||
|
||
/**
|
||
* 验签
|
||
*/
|
||
function doVerifySignature(msg, signHex, publicKey) {
|
||
var _ref3 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
|
||
der = _ref3.der,
|
||
hash = _ref3.hash,
|
||
userId = _ref3.userId;
|
||
|
||
var hashHex = typeof msg === 'string' ? _.utf8ToHex(msg) : _.arrayToHex(msg);
|
||
|
||
if (hash) {
|
||
// sm3杂凑
|
||
hashHex = getHash(hashHex, publicKey, userId);
|
||
}
|
||
|
||
var r = void 0;var s = void 0;
|
||
if (der) {
|
||
var decodeDerObj = decodeDer(signHex); // asn.1 der 解码
|
||
r = decodeDerObj.r;
|
||
s = decodeDerObj.s;
|
||
} else {
|
||
r = new BigInteger(signHex.substring(0, 64), 16);
|
||
s = new BigInteger(signHex.substring(64), 16);
|
||
}
|
||
|
||
var PA = curve.decodePointHex(publicKey);
|
||
var e = new BigInteger(hashHex, 16);
|
||
|
||
// t = (r + s) mod n
|
||
var t = r.add(s).mod(n);
|
||
|
||
if (t.equals(BigInteger.ZERO)) return false;
|
||
|
||
// x1y1 = s * G + t * PA
|
||
var x1y1 = G.multiply(s).add(PA.multiply(t));
|
||
|
||
// R = (e + x1) mod n
|
||
var R = e.add(x1y1.getX().toBigInteger()).mod(n);
|
||
|
||
return r.equals(R);
|
||
}
|
||
|
||
/**
|
||
* sm3杂凑算法
|
||
*/
|
||
function getHash(hashHex, publicKey) {
|
||
var userId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '1234567812345678';
|
||
|
||
// z = hash(entl || userId || a || b || gx || gy || px || py)
|
||
userId = _.utf8ToHex(userId);
|
||
var a = _.leftPad(G.curve.a.toBigInteger().toRadix(16), 64);
|
||
var b = _.leftPad(G.curve.b.toBigInteger().toRadix(16), 64);
|
||
var gx = _.leftPad(G.getX().toBigInteger().toRadix(16), 64);
|
||
var gy = _.leftPad(G.getY().toBigInteger().toRadix(16), 64);
|
||
if (publicKey.length > 128) publicKey = publicKey.substr(2, 128); // 干掉 '04'
|
||
var px = publicKey.substr(0, 64);
|
||
var py = publicKey.substr(64, 64);
|
||
var data = _.hexToArray(userId + a + b + gx + gy + px + py);
|
||
|
||
var entl = userId.length * 4;
|
||
data.unshift(entl & 0x00ff);
|
||
data.unshift(entl >> 8 & 0x00ff);
|
||
|
||
var z = sm3(data);
|
||
|
||
// e = hash(z || msg)
|
||
return _.arrayToHex(sm3(z.concat(_.hexToArray(hashHex))));
|
||
}
|
||
|
||
/**
|
||
* 计算公钥
|
||
*/
|
||
function getPublicKeyFromPrivateKey(privateKey) {
|
||
var PA = G.multiply(new BigInteger(privateKey, 16));
|
||
var x = _.leftPad(PA.getX().toBigInteger().toString(16), 64);
|
||
var y = _.leftPad(PA.getY().toBigInteger().toString(16), 64);
|
||
return '04' + x + y;
|
||
}
|
||
|
||
/**
|
||
* 获取椭圆曲线点
|
||
*/
|
||
function getPoint() {
|
||
var keypair = _.generateKeyPairHex();
|
||
var PA = curve.decodePointHex(keypair.publicKey);
|
||
|
||
keypair.k = new BigInteger(keypair.privateKey, 16);
|
||
keypair.x1 = PA.getX().toBigInteger();
|
||
|
||
return keypair;
|
||
}
|
||
|
||
module.exports = {
|
||
generateKeyPairHex: _.generateKeyPairHex,
|
||
doEncrypt: doEncrypt,
|
||
doDecrypt: doDecrypt,
|
||
doSignature: doSignature,
|
||
doVerifySignature: doVerifySignature,
|
||
getPoint: getPoint,
|
||
verifyPublicKey: _.verifyPublicKey
|
||
};
|
||
|
||
/***/ }),
|
||
/* 4 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
||
/* eslint-disable class-methods-use-this */
|
||
var _require = __webpack_require__(0),
|
||
BigInteger = _require.BigInteger;
|
||
|
||
function bigintToValue(bigint) {
|
||
var h = bigint.toString(16);
|
||
if (h[0] !== '-') {
|
||
// 正数
|
||
if (h.length % 2 === 1) h = '0' + h; // 补齐到整字节
|
||
else if (!h.match(/^[0-7]/)) h = '00' + h; // 非0开头,则补一个全0字节
|
||
} else {
|
||
// 负数
|
||
h = h.substr(1);
|
||
|
||
var len = h.length;
|
||
if (len % 2 === 1) len += 1; // 补齐到整字节
|
||
else if (!h.match(/^[0-7]/)) len += 2; // 非0开头,则补一个全0字节
|
||
|
||
var mask = '';
|
||
for (var i = 0; i < len; i++) {
|
||
mask += 'f';
|
||
}mask = new BigInteger(mask, 16);
|
||
|
||
// 对绝对值取反,加1
|
||
h = mask.xor(bigint).add(BigInteger.ONE);
|
||
h = h.toString(16).replace(/^-/, '');
|
||
}
|
||
return h;
|
||
}
|
||
|
||
var ASN1Object = function () {
|
||
function ASN1Object() {
|
||
_classCallCheck(this, ASN1Object);
|
||
|
||
this.tlv = null;
|
||
this.t = '00';
|
||
this.l = '00';
|
||
this.v = '';
|
||
}
|
||
|
||
/**
|
||
* 获取 der 编码比特流16进制串
|
||
*/
|
||
|
||
|
||
ASN1Object.prototype.getEncodedHex = function getEncodedHex() {
|
||
if (!this.tlv) {
|
||
this.v = this.getValue();
|
||
this.l = this.getLength();
|
||
this.tlv = this.t + this.l + this.v;
|
||
}
|
||
return this.tlv;
|
||
};
|
||
|
||
ASN1Object.prototype.getLength = function getLength() {
|
||
var n = this.v.length / 2; // 字节数
|
||
var nHex = n.toString(16);
|
||
if (nHex.length % 2 === 1) nHex = '0' + nHex; // 补齐到整字节
|
||
|
||
if (n < 128) {
|
||
// 短格式,以 0 开头
|
||
return nHex;
|
||
} else {
|
||
// 长格式,以 1 开头
|
||
var head = 128 + nHex.length / 2; // 1(1位) + 真正的长度占用字节数(7位) + 真正的长度
|
||
return head.toString(16) + nHex;
|
||
}
|
||
};
|
||
|
||
ASN1Object.prototype.getValue = function getValue() {
|
||
return '';
|
||
};
|
||
|
||
return ASN1Object;
|
||
}();
|
||
|
||
var DERInteger = function (_ASN1Object) {
|
||
_inherits(DERInteger, _ASN1Object);
|
||
|
||
function DERInteger(bigint) {
|
||
_classCallCheck(this, DERInteger);
|
||
|
||
var _this = _possibleConstructorReturn(this, _ASN1Object.call(this));
|
||
|
||
_this.t = '02'; // 整型标签说明
|
||
if (bigint) _this.v = bigintToValue(bigint);
|
||
return _this;
|
||
}
|
||
|
||
DERInteger.prototype.getValue = function getValue() {
|
||
return this.v;
|
||
};
|
||
|
||
return DERInteger;
|
||
}(ASN1Object);
|
||
|
||
var DERSequence = function (_ASN1Object2) {
|
||
_inherits(DERSequence, _ASN1Object2);
|
||
|
||
function DERSequence(asn1Array) {
|
||
_classCallCheck(this, DERSequence);
|
||
|
||
var _this2 = _possibleConstructorReturn(this, _ASN1Object2.call(this));
|
||
|
||
_this2.t = '30'; // 序列标签说明
|
||
_this2.asn1Array = asn1Array;
|
||
return _this2;
|
||
}
|
||
|
||
DERSequence.prototype.getValue = function getValue() {
|
||
this.v = this.asn1Array.map(function (asn1Object) {
|
||
return asn1Object.getEncodedHex();
|
||
}).join('');
|
||
return this.v;
|
||
};
|
||
|
||
return DERSequence;
|
||
}(ASN1Object);
|
||
|
||
/**
|
||
* 获取 l 占用字节数
|
||
*/
|
||
|
||
|
||
function getLenOfL(str, start) {
|
||
if (+str[start + 2] < 8) return 1; // l 以0开头,则表示短格式,只占一个字节
|
||
return +str.substr(start + 2, 2) & 0x7f + 1; // 长格式,取第一个字节后7位作为长度真正占用字节数,再加上本身
|
||
}
|
||
|
||
/**
|
||
* 获取 l
|
||
*/
|
||
function getL(str, start) {
|
||
// 获取 l
|
||
var len = getLenOfL(str, start);
|
||
var l = str.substr(start + 2, len * 2);
|
||
|
||
if (!l) return -1;
|
||
var bigint = +l[0] < 8 ? new BigInteger(l, 16) : new BigInteger(l.substr(2), 16);
|
||
|
||
return bigint.intValue();
|
||
}
|
||
|
||
/**
|
||
* 获取 v 的位置
|
||
*/
|
||
function getStartOfV(str, start) {
|
||
var len = getLenOfL(str, start);
|
||
return start + (len + 1) * 2;
|
||
}
|
||
|
||
module.exports = {
|
||
/**
|
||
* ASN.1 der 编码,针对 sm2 签名
|
||
*/
|
||
encodeDer: function encodeDer(r, s) {
|
||
var derR = new DERInteger(r);
|
||
var derS = new DERInteger(s);
|
||
var derSeq = new DERSequence([derR, derS]);
|
||
|
||
return derSeq.getEncodedHex();
|
||
},
|
||
|
||
|
||
/**
|
||
* 解析 ASN.1 der,针对 sm2 验签
|
||
*/
|
||
decodeDer: function decodeDer(input) {
|
||
// 结构:
|
||
// input = | tSeq | lSeq | vSeq |
|
||
// vSeq = | tR | lR | vR | tS | lS | vS |
|
||
var start = getStartOfV(input, 0);
|
||
|
||
var vIndexR = getStartOfV(input, start);
|
||
var lR = getL(input, start);
|
||
var vR = input.substr(vIndexR, lR * 2);
|
||
|
||
var nextStart = vIndexR + vR.length;
|
||
var vIndexS = getStartOfV(input, nextStart);
|
||
var lS = getL(input, nextStart);
|
||
var vS = input.substr(vIndexS, lS * 2);
|
||
|
||
var r = new BigInteger(vR, 16);
|
||
var s = new BigInteger(vS, 16);
|
||
|
||
return { r: r, s: s };
|
||
}
|
||
};
|
||
|
||
/***/ }),
|
||
/* 5 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
/* eslint-disable no-bitwise, no-mixed-operators, no-use-before-define, max-len */
|
||
var _require = __webpack_require__(0),
|
||
BigInteger = _require.BigInteger,
|
||
SecureRandom = _require.SecureRandom;
|
||
|
||
var _require2 = __webpack_require__(6),
|
||
ECCurveFp = _require2.ECCurveFp;
|
||
|
||
var rng = new SecureRandom();
|
||
|
||
var _generateEcparam = generateEcparam(),
|
||
curve = _generateEcparam.curve,
|
||
G = _generateEcparam.G,
|
||
n = _generateEcparam.n;
|
||
|
||
/**
|
||
* 获取公共椭圆曲线
|
||
*/
|
||
|
||
|
||
function getGlobalCurve() {
|
||
return curve;
|
||
}
|
||
|
||
/**
|
||
* 生成ecparam
|
||
*/
|
||
function generateEcparam() {
|
||
// 椭圆曲线
|
||
var p = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16);
|
||
var a = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 16);
|
||
var b = new BigInteger('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16);
|
||
var curve = new ECCurveFp(p, a, b);
|
||
|
||
// 基点
|
||
var gxHex = '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7';
|
||
var gyHex = 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0';
|
||
var G = curve.decodePointHex('04' + gxHex + gyHex);
|
||
|
||
var n = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 16);
|
||
|
||
return { curve: curve, G: G, n: n };
|
||
}
|
||
|
||
/**
|
||
* 生成密钥对:publicKey = privateKey * G
|
||
*/
|
||
function generateKeyPairHex(a, b, c) {
|
||
var random = a ? new BigInteger(a, b, c) : new BigInteger(n.bitLength(), rng);
|
||
var d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE); // 随机数
|
||
var privateKey = leftPad(d.toString(16), 64);
|
||
|
||
var P = G.multiply(d); // P = dG,p 为公钥,d 为私钥
|
||
var Px = leftPad(P.getX().toBigInteger().toString(16), 64);
|
||
var Py = leftPad(P.getY().toBigInteger().toString(16), 64);
|
||
var publicKey = '04' + Px + Py;
|
||
|
||
return { privateKey: privateKey, publicKey: publicKey };
|
||
}
|
||
|
||
/**
|
||
* utf8串转16进制串
|
||
*/
|
||
function utf8ToHex(input) {
|
||
input = unescape(encodeURIComponent(input));
|
||
|
||
var length = input.length;
|
||
|
||
// 转换到字数组
|
||
var words = [];
|
||
for (var i = 0; i < length; i++) {
|
||
words[i >>> 2] |= (input.charCodeAt(i) & 0xff) << 24 - i % 4 * 8;
|
||
}
|
||
|
||
// 转换到16进制
|
||
var hexChars = [];
|
||
for (var _i = 0; _i < length; _i++) {
|
||
var bite = words[_i >>> 2] >>> 24 - _i % 4 * 8 & 0xff;
|
||
hexChars.push((bite >>> 4).toString(16));
|
||
hexChars.push((bite & 0x0f).toString(16));
|
||
}
|
||
|
||
return hexChars.join('');
|
||
}
|
||
|
||
/**
|
||
* 补全16进制字符串
|
||
*/
|
||
function leftPad(input, num) {
|
||
if (input.length >= num) return input;
|
||
|
||
return new Array(num - input.length + 1).join('0') + input;
|
||
}
|
||
|
||
/**
|
||
* 转成16进制串
|
||
*/
|
||
function arrayToHex(arr) {
|
||
return arr.map(function (item) {
|
||
item = item.toString(16);
|
||
return item.length === 1 ? '0' + item : item;
|
||
}).join('');
|
||
}
|
||
|
||
/**
|
||
* 转成utf8串
|
||
*/
|
||
function arrayToUtf8(arr) {
|
||
var words = [];
|
||
var j = 0;
|
||
for (var i = 0; i < arr.length * 2; i += 2) {
|
||
words[i >>> 3] |= parseInt(arr[j], 10) << 24 - i % 8 * 4;
|
||
j++;
|
||
}
|
||
|
||
try {
|
||
var latin1Chars = [];
|
||
|
||
for (var _i2 = 0; _i2 < arr.length; _i2++) {
|
||
var bite = words[_i2 >>> 2] >>> 24 - _i2 % 4 * 8 & 0xff;
|
||
latin1Chars.push(String.fromCharCode(bite));
|
||
}
|
||
|
||
return decodeURIComponent(escape(latin1Chars.join('')));
|
||
} catch (e) {
|
||
throw new Error('Malformed UTF-8 data');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 转成字节数组
|
||
*/
|
||
function hexToArray(hexStr) {
|
||
var words = [];
|
||
var hexStrLength = hexStr.length;
|
||
|
||
if (hexStrLength % 2 !== 0) {
|
||
hexStr = leftPad(hexStr, hexStrLength + 1);
|
||
}
|
||
|
||
hexStrLength = hexStr.length;
|
||
|
||
for (var i = 0; i < hexStrLength; i += 2) {
|
||
words.push(parseInt(hexStr.substr(i, 2), 16));
|
||
}
|
||
return words;
|
||
}
|
||
|
||
/**
|
||
* 验证公钥是否为椭圆曲线上的点
|
||
*/
|
||
function verifyPublicKey(publicKey) {
|
||
var point = curve.decodePointHex(publicKey);
|
||
if (!point) return false;
|
||
|
||
var x = point.getX();
|
||
var y = point.getY();
|
||
|
||
// 验证 y^2 是否等于 x^3 + ax + b
|
||
return y.square().equals(x.multiply(x.square()).add(x.multiply(curve.a)).add(curve.b));
|
||
}
|
||
|
||
module.exports = {
|
||
getGlobalCurve: getGlobalCurve,
|
||
generateEcparam: generateEcparam,
|
||
generateKeyPairHex: generateKeyPairHex,
|
||
utf8ToHex: utf8ToHex,
|
||
leftPad: leftPad,
|
||
arrayToHex: arrayToHex,
|
||
arrayToUtf8: arrayToUtf8,
|
||
hexToArray: hexToArray,
|
||
verifyPublicKey: verifyPublicKey
|
||
};
|
||
|
||
/***/ }),
|
||
/* 6 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
||
/* eslint-disable no-case-declarations, max-len */
|
||
var _require = __webpack_require__(0),
|
||
BigInteger = _require.BigInteger;
|
||
|
||
/**
|
||
* thanks for Tom Wu : http://www-cs-students.stanford.edu/~tjw/jsbn/
|
||
*
|
||
* Basic Javascript Elliptic Curve implementation
|
||
* Ported loosely from BouncyCastle's Java EC code
|
||
* Only Fp curves implemented for now
|
||
*/
|
||
|
||
var THREE = new BigInteger('3');
|
||
|
||
/**
|
||
* 椭圆曲线域元素
|
||
*/
|
||
|
||
var ECFieldElementFp = function () {
|
||
function ECFieldElementFp(q, x) {
|
||
_classCallCheck(this, ECFieldElementFp);
|
||
|
||
this.x = x;
|
||
this.q = q;
|
||
// TODO if (x.compareTo(q) >= 0) error
|
||
}
|
||
|
||
/**
|
||
* 判断相等
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.equals = function equals(other) {
|
||
if (other === this) return true;
|
||
return this.q.equals(other.q) && this.x.equals(other.x);
|
||
};
|
||
|
||
/**
|
||
* 返回具体数值
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.toBigInteger = function toBigInteger() {
|
||
return this.x;
|
||
};
|
||
|
||
/**
|
||
* 取反
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.negate = function negate() {
|
||
return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));
|
||
};
|
||
|
||
/**
|
||
* 相加
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.add = function add(b) {
|
||
return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q));
|
||
};
|
||
|
||
/**
|
||
* 相减
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.subtract = function subtract(b) {
|
||
return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q));
|
||
};
|
||
|
||
/**
|
||
* 相乘
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.multiply = function multiply(b) {
|
||
return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q));
|
||
};
|
||
|
||
/**
|
||
* 相除
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.divide = function divide(b) {
|
||
return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q));
|
||
};
|
||
|
||
/**
|
||
* 平方
|
||
*/
|
||
|
||
|
||
ECFieldElementFp.prototype.square = function square() {
|
||
return new ECFieldElementFp(this.q, this.x.square().mod(this.q));
|
||
};
|
||
|
||
return ECFieldElementFp;
|
||
}();
|
||
|
||
var ECPointFp = function () {
|
||
function ECPointFp(curve, x, y, z) {
|
||
_classCallCheck(this, ECPointFp);
|
||
|
||
this.curve = curve;
|
||
this.x = x;
|
||
this.y = y;
|
||
// 标准射影坐标系:zinv == null 或 z * zinv == 1
|
||
this.z = z == null ? BigInteger.ONE : z;
|
||
this.zinv = null;
|
||
// TODO: compression flag
|
||
}
|
||
|
||
ECPointFp.prototype.getX = function getX() {
|
||
if (this.zinv === null) this.zinv = this.z.modInverse(this.curve.q);
|
||
|
||
return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));
|
||
};
|
||
|
||
ECPointFp.prototype.getY = function getY() {
|
||
if (this.zinv === null) this.zinv = this.z.modInverse(this.curve.q);
|
||
|
||
return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));
|
||
};
|
||
|
||
/**
|
||
* 判断相等
|
||
*/
|
||
|
||
|
||
ECPointFp.prototype.equals = function equals(other) {
|
||
if (other === this) return true;
|
||
if (this.isInfinity()) return other.isInfinity();
|
||
if (other.isInfinity()) return this.isInfinity();
|
||
|
||
// u = y2 * z1 - y1 * z2
|
||
var u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q);
|
||
if (!u.equals(BigInteger.ZERO)) return false;
|
||
|
||
// v = x2 * z1 - x1 * z2
|
||
var v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q);
|
||
return v.equals(BigInteger.ZERO);
|
||
};
|
||
|
||
/**
|
||
* 是否是无穷远点
|
||
*/
|
||
|
||
|
||
ECPointFp.prototype.isInfinity = function isInfinity() {
|
||
if (this.x === null && this.y === null) return true;
|
||
return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);
|
||
};
|
||
|
||
/**
|
||
* 取反,x 轴对称点
|
||
*/
|
||
|
||
|
||
ECPointFp.prototype.negate = function negate() {
|
||
return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);
|
||
};
|
||
|
||
/**
|
||
* 相加
|
||
*
|
||
* 标准射影坐标系:
|
||
*
|
||
* λ1 = x1 * z2
|
||
* λ2 = x2 * z1
|
||
* λ3 = λ1 − λ2
|
||
* λ4 = y1 * z2
|
||
* λ5 = y2 * z1
|
||
* λ6 = λ4 − λ5
|
||
* λ7 = λ1 + λ2
|
||
* λ8 = z1 * z2
|
||
* λ9 = λ3^2
|
||
* λ10 = λ3 * λ9
|
||
* λ11 = λ8 * λ6^2 − λ7 * λ9
|
||
* x3 = λ3 * λ11
|
||
* y3 = λ6 * (λ9 * λ1 − λ11) − λ4 * λ10
|
||
* z3 = λ10 * λ8
|
||
*/
|
||
|
||
|
||
ECPointFp.prototype.add = function add(b) {
|
||
if (this.isInfinity()) return b;
|
||
if (b.isInfinity()) return this;
|
||
|
||
var x1 = this.x.toBigInteger();
|
||
var y1 = this.y.toBigInteger();
|
||
var z1 = this.z;
|
||
var x2 = b.x.toBigInteger();
|
||
var y2 = b.y.toBigInteger();
|
||
var z2 = b.z;
|
||
var q = this.curve.q;
|
||
|
||
var w1 = x1.multiply(z2).mod(q);
|
||
var w2 = x2.multiply(z1).mod(q);
|
||
var w3 = w1.subtract(w2);
|
||
var w4 = y1.multiply(z2).mod(q);
|
||
var w5 = y2.multiply(z1).mod(q);
|
||
var w6 = w4.subtract(w5);
|
||
|
||
if (BigInteger.ZERO.equals(w3)) {
|
||
if (BigInteger.ZERO.equals(w6)) {
|
||
return this.twice(); // this == b,计算自加
|
||
}
|
||
return this.curve.infinity; // this == -b,则返回无穷远点
|
||
}
|
||
|
||
var w7 = w1.add(w2);
|
||
var w8 = z1.multiply(z2).mod(q);
|
||
var w9 = w3.square().mod(q);
|
||
var w10 = w3.multiply(w9).mod(q);
|
||
var w11 = w8.multiply(w6.square()).subtract(w7.multiply(w9)).mod(q);
|
||
|
||
var x3 = w3.multiply(w11).mod(q);
|
||
var y3 = w6.multiply(w9.multiply(w1).subtract(w11)).subtract(w4.multiply(w10)).mod(q);
|
||
var z3 = w10.multiply(w8).mod(q);
|
||
|
||
return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
|
||
};
|
||
|
||
/**
|
||
* 自加
|
||
*
|
||
* 标准射影坐标系:
|
||
*
|
||
* λ1 = 3 * x1^2 + a * z1^2
|
||
* λ2 = 2 * y1 * z1
|
||
* λ3 = y1^2
|
||
* λ4 = λ3 * x1 * z1
|
||
* λ5 = λ2^2
|
||
* λ6 = λ1^2 − 8 * λ4
|
||
* x3 = λ2 * λ6
|
||
* y3 = λ1 * (4 * λ4 − λ6) − 2 * λ5 * λ3
|
||
* z3 = λ2 * λ5
|
||
*/
|
||
|
||
|
||
ECPointFp.prototype.twice = function twice() {
|
||
if (this.isInfinity()) return this;
|
||
if (!this.y.toBigInteger().signum()) return this.curve.infinity;
|
||
|
||
var x1 = this.x.toBigInteger();
|
||
var y1 = this.y.toBigInteger();
|
||
var z1 = this.z;
|
||
var q = this.curve.q;
|
||
var a = this.curve.a.toBigInteger();
|
||
|
||
var w1 = x1.square().multiply(THREE).add(a.multiply(z1.square())).mod(q);
|
||
var w2 = y1.shiftLeft(1).multiply(z1).mod(q);
|
||
var w3 = y1.square().mod(q);
|
||
var w4 = w3.multiply(x1).multiply(z1).mod(q);
|
||
var w5 = w2.square().mod(q);
|
||
var w6 = w1.square().subtract(w4.shiftLeft(3)).mod(q);
|
||
|
||
var x3 = w2.multiply(w6).mod(q);
|
||
var y3 = w1.multiply(w4.shiftLeft(2).subtract(w6)).subtract(w5.shiftLeft(1).multiply(w3)).mod(q);
|
||
var z3 = w2.multiply(w5).mod(q);
|
||
|
||
return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
|
||
};
|
||
|
||
/**
|
||
* 倍点计算
|
||
*/
|
||
|
||
|
||
ECPointFp.prototype.multiply = function multiply(k) {
|
||
if (this.isInfinity()) return this;
|
||
if (!k.signum()) return this.curve.infinity;
|
||
|
||
// 使用加减法
|
||
var k3 = k.multiply(THREE);
|
||
var neg = this.negate();
|
||
var Q = this;
|
||
|
||
for (var i = k3.bitLength() - 2; i > 0; i--) {
|
||
Q = Q.twice();
|
||
|
||
var k3Bit = k3.testBit(i);
|
||
var kBit = k.testBit(i);
|
||
|
||
if (k3Bit !== kBit) {
|
||
Q = Q.add(k3Bit ? this : neg);
|
||
}
|
||
}
|
||
|
||
return Q;
|
||
};
|
||
|
||
return ECPointFp;
|
||
}();
|
||
|
||
/**
|
||
* 椭圆曲线 y^2 = x^3 + ax + b
|
||
*/
|
||
|
||
|
||
var ECCurveFp = function () {
|
||
function ECCurveFp(q, a, b) {
|
||
_classCallCheck(this, ECCurveFp);
|
||
|
||
this.q = q;
|
||
this.a = this.fromBigInteger(a);
|
||
this.b = this.fromBigInteger(b);
|
||
this.infinity = new ECPointFp(this, null, null); // 无穷远点
|
||
}
|
||
|
||
/**
|
||
* 判断两个椭圆曲线是否相等
|
||
*/
|
||
|
||
|
||
ECCurveFp.prototype.equals = function equals(other) {
|
||
if (other === this) return true;
|
||
return this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b);
|
||
};
|
||
|
||
/**
|
||
* 生成椭圆曲线域元素
|
||
*/
|
||
|
||
|
||
ECCurveFp.prototype.fromBigInteger = function fromBigInteger(x) {
|
||
return new ECFieldElementFp(this.q, x);
|
||
};
|
||
|
||
/**
|
||
* 解析 16 进制串为椭圆曲线点
|
||
*/
|
||
|
||
|
||
ECCurveFp.prototype.decodePointHex = function decodePointHex(s) {
|
||
switch (parseInt(s.substr(0, 2), 16)) {
|
||
// 第一个字节
|
||
case 0:
|
||
return this.infinity;
|
||
case 2:
|
||
case 3:
|
||
// 不支持的压缩方式
|
||
return null;
|
||
case 4:
|
||
case 6:
|
||
case 7:
|
||
var len = (s.length - 2) / 2;
|
||
var xHex = s.substr(2, len);
|
||
var yHex = s.substr(len + 2, len);
|
||
|
||
return new ECPointFp(this, this.fromBigInteger(new BigInteger(xHex, 16)), this.fromBigInteger(new BigInteger(yHex, 16)));
|
||
default:
|
||
// 不支持
|
||
return null;
|
||
}
|
||
};
|
||
|
||
return ECCurveFp;
|
||
}();
|
||
|
||
module.exports = {
|
||
ECPointFp: ECPointFp,
|
||
ECCurveFp: ECCurveFp
|
||
};
|
||
|
||
/***/ }),
|
||
/* 7 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
var _require = __webpack_require__(1),
|
||
sm3 = _require.sm3,
|
||
hmac = _require.hmac;
|
||
|
||
/**
|
||
* 补全16进制字符串
|
||
*/
|
||
|
||
|
||
function leftPad(input, num) {
|
||
if (input.length >= num) return input;
|
||
|
||
return new Array(num - input.length + 1).join('0') + input;
|
||
}
|
||
|
||
/**
|
||
* 字节数组转 16 进制串
|
||
*/
|
||
function ArrayToHex(arr) {
|
||
return arr.map(function (item) {
|
||
item = item.toString(16);
|
||
return item.length === 1 ? '0' + item : item;
|
||
}).join('');
|
||
}
|
||
|
||
/**
|
||
* 转成字节数组
|
||
*/
|
||
function hexToArray(hexStr) {
|
||
var words = [];
|
||
var hexStrLength = hexStr.length;
|
||
|
||
if (hexStrLength % 2 !== 0) {
|
||
hexStr = leftPad(hexStr, hexStrLength + 1);
|
||
}
|
||
|
||
hexStrLength = hexStr.length;
|
||
|
||
for (var i = 0; i < hexStrLength; i += 2) {
|
||
words.push(parseInt(hexStr.substr(i, 2), 16));
|
||
}
|
||
return words;
|
||
}
|
||
|
||
/**
|
||
* utf8 串转字节数组
|
||
*/
|
||
function utf8ToArray(str) {
|
||
var arr = [];
|
||
|
||
for (var i = 0, len = str.length; i < len; i++) {
|
||
var point = str.codePointAt(i);
|
||
|
||
if (point <= 0x007f) {
|
||
// 单字节,标量值:00000000 00000000 0zzzzzzz
|
||
arr.push(point);
|
||
} else if (point <= 0x07ff) {
|
||
// 双字节,标量值:00000000 00000yyy yyzzzzzz
|
||
arr.push(0xc0 | point >>> 6); // 110yyyyy(0xc0-0xdf)
|
||
arr.push(0x80 | point & 0x3f); // 10zzzzzz(0x80-0xbf)
|
||
} else if (point <= 0xD7FF || point >= 0xE000 && point <= 0xFFFF) {
|
||
// 三字节:标量值:00000000 xxxxyyyy yyzzzzzz
|
||
arr.push(0xe0 | point >>> 12); // 1110xxxx(0xe0-0xef)
|
||
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy(0x80-0xbf)
|
||
arr.push(0x80 | point & 0x3f); // 10zzzzzz(0x80-0xbf)
|
||
} else if (point >= 0x010000 && point <= 0x10FFFF) {
|
||
// 四字节:标量值:000wwwxx xxxxyyyy yyzzzzzz
|
||
i++;
|
||
arr.push(0xf0 | point >>> 18 & 0x1c); // 11110www(0xf0-0xf7)
|
||
arr.push(0x80 | point >>> 12 & 0x3f); // 10xxxxxx(0x80-0xbf)
|
||
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy(0x80-0xbf)
|
||
arr.push(0x80 | point & 0x3f); // 10zzzzzz(0x80-0xbf)
|
||
} else {
|
||
// 五、六字节,暂时不支持
|
||
arr.push(point);
|
||
throw new Error('input is not supported');
|
||
}
|
||
}
|
||
|
||
return arr;
|
||
}
|
||
|
||
module.exports = function (input, options) {
|
||
input = typeof input === 'string' ? utf8ToArray(input) : Array.prototype.slice.call(input);
|
||
|
||
if (options) {
|
||
var mode = options.mode || 'hmac';
|
||
if (mode !== 'hmac') throw new Error('invalid mode');
|
||
|
||
var key = options.key;
|
||
if (!key) throw new Error('invalid key');
|
||
|
||
key = typeof key === 'string' ? hexToArray(key) : Array.prototype.slice.call(key);
|
||
return ArrayToHex(hmac(input, key));
|
||
}
|
||
|
||
return ArrayToHex(sm3(input));
|
||
};
|
||
|
||
/***/ }),
|
||
/* 8 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
"use strict";
|
||
|
||
|
||
/* eslint-disable no-bitwise, no-mixed-operators, complexity */
|
||
var DECRYPT = 0;
|
||
var ROUND = 32;
|
||
var BLOCK = 16;
|
||
|
||
var Sbox = [0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48];
|
||
|
||
var CK = [0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279];
|
||
|
||
/**
|
||
* 16 进制串转字节数组
|
||
*/
|
||
function hexToArray(str) {
|
||
var arr = [];
|
||
for (var i = 0, len = str.length; i < len; i += 2) {
|
||
arr.push(parseInt(str.substr(i, 2), 16));
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
/**
|
||
* 字节数组转 16 进制串
|
||
*/
|
||
function ArrayToHex(arr) {
|
||
return arr.map(function (item) {
|
||
item = item.toString(16);
|
||
return item.length === 1 ? '0' + item : item;
|
||
}).join('');
|
||
}
|
||
|
||
/**
|
||
* utf8 串转字节数组
|
||
*/
|
||
function utf8ToArray(str) {
|
||
var arr = [];
|
||
|
||
for (var i = 0, len = str.length; i < len; i++) {
|
||
var point = str.codePointAt(i);
|
||
|
||
if (point <= 0x007f) {
|
||
// 单字节,标量值:00000000 00000000 0zzzzzzz
|
||
arr.push(point);
|
||
} else if (point <= 0x07ff) {
|
||
// 双字节,标量值:00000000 00000yyy yyzzzzzz
|
||
arr.push(0xc0 | point >>> 6); // 110yyyyy(0xc0-0xdf)
|
||
arr.push(0x80 | point & 0x3f); // 10zzzzzz(0x80-0xbf)
|
||
} else if (point <= 0xD7FF || point >= 0xE000 && point <= 0xFFFF) {
|
||
// 三字节:标量值:00000000 xxxxyyyy yyzzzzzz
|
||
arr.push(0xe0 | point >>> 12); // 1110xxxx(0xe0-0xef)
|
||
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy(0x80-0xbf)
|
||
arr.push(0x80 | point & 0x3f); // 10zzzzzz(0x80-0xbf)
|
||
} else if (point >= 0x010000 && point <= 0x10FFFF) {
|
||
// 四字节:标量值:000wwwxx xxxxyyyy yyzzzzzz
|
||
i++;
|
||
arr.push(0xf0 | point >>> 18 & 0x1c); // 11110www(0xf0-0xf7)
|
||
arr.push(0x80 | point >>> 12 & 0x3f); // 10xxxxxx(0x80-0xbf)
|
||
arr.push(0x80 | point >>> 6 & 0x3f); // 10yyyyyy(0x80-0xbf)
|
||
arr.push(0x80 | point & 0x3f); // 10zzzzzz(0x80-0xbf)
|
||
} else {
|
||
// 五、六字节,暂时不支持
|
||
arr.push(point);
|
||
throw new Error('input is not supported');
|
||
}
|
||
}
|
||
|
||
return arr;
|
||
}
|
||
|
||
/**
|
||
* 字节数组转 utf8 串
|
||
*/
|
||
function arrayToUtf8(arr) {
|
||
var str = [];
|
||
for (var i = 0, len = arr.length; i < len; i++) {
|
||
if (arr[i] >= 0xf0 && arr[i] <= 0xf7) {
|
||
// 四字节
|
||
str.push(String.fromCodePoint(((arr[i] & 0x07) << 18) + ((arr[i + 1] & 0x3f) << 12) + ((arr[i + 2] & 0x3f) << 6) + (arr[i + 3] & 0x3f)));
|
||
i += 3;
|
||
} else if (arr[i] >= 0xe0 && arr[i] <= 0xef) {
|
||
// 三字节
|
||
str.push(String.fromCodePoint(((arr[i] & 0x0f) << 12) + ((arr[i + 1] & 0x3f) << 6) + (arr[i + 2] & 0x3f)));
|
||
i += 2;
|
||
} else if (arr[i] >= 0xc0 && arr[i] <= 0xdf) {
|
||
// 双字节
|
||
str.push(String.fromCodePoint(((arr[i] & 0x1f) << 6) + (arr[i + 1] & 0x3f)));
|
||
i++;
|
||
} else {
|
||
// 单字节
|
||
str.push(String.fromCodePoint(arr[i]));
|
||
}
|
||
}
|
||
|
||
return str.join('');
|
||
}
|
||
|
||
/**
|
||
* 32 比特循环左移
|
||
*/
|
||
function rotl(x, y) {
|
||
return x << y | x >>> 32 - y;
|
||
}
|
||
|
||
/**
|
||
* 非线性变换
|
||
*/
|
||
function byteSub(a) {
|
||
return (Sbox[a >>> 24 & 0xFF] & 0xFF) << 24 | (Sbox[a >>> 16 & 0xFF] & 0xFF) << 16 | (Sbox[a >>> 8 & 0xFF] & 0xFF) << 8 | Sbox[a & 0xFF] & 0xFF;
|
||
}
|
||
|
||
/**
|
||
* 线性变换,加密/解密用
|
||
*/
|
||
function l1(b) {
|
||
return b ^ rotl(b, 2) ^ rotl(b, 10) ^ rotl(b, 18) ^ rotl(b, 24);
|
||
}
|
||
|
||
/**
|
||
* 线性变换,生成轮密钥用
|
||
*/
|
||
function l2(b) {
|
||
return b ^ rotl(b, 13) ^ rotl(b, 23);
|
||
}
|
||
|
||
/**
|
||
* 以一组 128 比特进行加密/解密操作
|
||
*/
|
||
function sms4Crypt(input, output, roundKey) {
|
||
var x = new Array(4);
|
||
|
||
// 字节数组转成字数组(此处 1 字 = 32 比特)
|
||
var tmp = new Array(4);
|
||
for (var i = 0; i < 4; i++) {
|
||
tmp[0] = input[4 * i] & 0xff;
|
||
tmp[1] = input[4 * i + 1] & 0xff;
|
||
tmp[2] = input[4 * i + 2] & 0xff;
|
||
tmp[3] = input[4 * i + 3] & 0xff;
|
||
x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
|
||
}
|
||
|
||
// x[i + 4] = x[i] ^ l1(byteSub(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ roundKey[i]))
|
||
for (var r = 0, mid; r < 32; r += 4) {
|
||
mid = x[1] ^ x[2] ^ x[3] ^ roundKey[r + 0];
|
||
x[0] ^= l1(byteSub(mid)); // x[4]
|
||
|
||
mid = x[2] ^ x[3] ^ x[0] ^ roundKey[r + 1];
|
||
x[1] ^= l1(byteSub(mid)); // x[5]
|
||
|
||
mid = x[3] ^ x[0] ^ x[1] ^ roundKey[r + 2];
|
||
x[2] ^= l1(byteSub(mid)); // x[6]
|
||
|
||
mid = x[0] ^ x[1] ^ x[2] ^ roundKey[r + 3];
|
||
x[3] ^= l1(byteSub(mid)); // x[7]
|
||
}
|
||
|
||
// 反序变换
|
||
for (var j = 0; j < 16; j += 4) {
|
||
output[j] = x[3 - j / 4] >>> 24 & 0xff;
|
||
output[j + 1] = x[3 - j / 4] >>> 16 & 0xff;
|
||
output[j + 2] = x[3 - j / 4] >>> 8 & 0xff;
|
||
output[j + 3] = x[3 - j / 4] & 0xff;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 密钥扩展算法
|
||
*/
|
||
function sms4KeyExt(key, roundKey, cryptFlag) {
|
||
var x = new Array(4);
|
||
|
||
// 字节数组转成字数组(此处 1 字 = 32 比特)
|
||
var tmp = new Array(4);
|
||
for (var i = 0; i < 4; i++) {
|
||
tmp[0] = key[0 + 4 * i] & 0xff;
|
||
tmp[1] = key[1 + 4 * i] & 0xff;
|
||
tmp[2] = key[2 + 4 * i] & 0xff;
|
||
tmp[3] = key[3 + 4 * i] & 0xff;
|
||
x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
|
||
}
|
||
|
||
// 与系统参数做异或
|
||
x[0] ^= 0xa3b1bac6;
|
||
x[1] ^= 0x56aa3350;
|
||
x[2] ^= 0x677d9197;
|
||
x[3] ^= 0xb27022dc;
|
||
|
||
// roundKey[i] = x[i + 4] = x[i] ^ l2(byteSub(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ CK[i]))
|
||
for (var r = 0, mid; r < 32; r += 4) {
|
||
mid = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
|
||
roundKey[r + 0] = x[0] ^= l2(byteSub(mid)); // x[4]
|
||
|
||
mid = x[2] ^ x[3] ^ x[0] ^ CK[r + 1];
|
||
roundKey[r + 1] = x[1] ^= l2(byteSub(mid)); // x[5]
|
||
|
||
mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
|
||
roundKey[r + 2] = x[2] ^= l2(byteSub(mid)); // x[6]
|
||
|
||
mid = x[0] ^ x[1] ^ x[2] ^ CK[r + 3];
|
||
roundKey[r + 3] = x[3] ^= l2(byteSub(mid)); // x[7]
|
||
}
|
||
|
||
// 解密时使用反序的轮密钥
|
||
if (cryptFlag === DECRYPT) {
|
||
for (var _r = 0, _mid; _r < 16; _r++) {
|
||
_mid = roundKey[_r];
|
||
roundKey[_r] = roundKey[31 - _r];
|
||
roundKey[31 - _r] = _mid;
|
||
}
|
||
}
|
||
}
|
||
|
||
function sm4(inArray, key, cryptFlag) {
|
||
var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},
|
||
_ref$padding = _ref.padding,
|
||
padding = _ref$padding === undefined ? 'pkcs#7' : _ref$padding,
|
||
mode = _ref.mode,
|
||
_ref$iv = _ref.iv,
|
||
iv = _ref$iv === undefined ? [] : _ref$iv,
|
||
_ref$output = _ref.output,
|
||
output = _ref$output === undefined ? 'string' : _ref$output;
|
||
|
||
if (mode === 'cbc') {
|
||
// CBC 模式,默认走 ECB 模式
|
||
if (typeof iv === 'string') iv = hexToArray(iv);
|
||
if (iv.length !== 128 / 8) {
|
||
// iv 不是 128 比特
|
||
throw new Error('iv is invalid');
|
||
}
|
||
}
|
||
|
||
// 检查 key
|
||
if (typeof key === 'string') key = hexToArray(key);
|
||
if (key.length !== 128 / 8) {
|
||
// key 不是 128 比特
|
||
throw new Error('key is invalid');
|
||
}
|
||
|
||
// 检查输入
|
||
if (typeof inArray === 'string') {
|
||
if (cryptFlag !== DECRYPT) {
|
||
// 加密,输入为 utf8 串
|
||
inArray = utf8ToArray(inArray);
|
||
} else {
|
||
// 解密,输入为 16 进制串
|
||
inArray = hexToArray(inArray);
|
||
}
|
||
} else {
|
||
inArray = [].concat(inArray);
|
||
}
|
||
|
||
// 新增填充,sm4 是 16 个字节一个分组,所以统一走到 pkcs#7
|
||
if ((padding === 'pkcs#5' || padding === 'pkcs#7') && cryptFlag !== DECRYPT) {
|
||
var paddingCount = BLOCK - inArray.length % BLOCK;
|
||
for (var i = 0; i < paddingCount; i++) {
|
||
inArray.push(paddingCount);
|
||
}
|
||
}
|
||
|
||
// 生成轮密钥
|
||
var roundKey = new Array(ROUND);
|
||
sms4KeyExt(key, roundKey, cryptFlag);
|
||
|
||
var outArray = [];
|
||
var lastVector = iv;
|
||
var restLen = inArray.length;
|
||
var point = 0;
|
||
while (restLen >= BLOCK) {
|
||
var input = inArray.slice(point, point + 16);
|
||
var _output = new Array(16);
|
||
|
||
if (mode === 'cbc') {
|
||
for (var _i = 0; _i < BLOCK; _i++) {
|
||
if (cryptFlag !== DECRYPT) {
|
||
// 加密过程在组加密前进行异或
|
||
input[_i] ^= lastVector[_i];
|
||
}
|
||
}
|
||
}
|
||
|
||
sms4Crypt(input, _output, roundKey);
|
||
|
||
for (var _i2 = 0; _i2 < BLOCK; _i2++) {
|
||
if (mode === 'cbc') {
|
||
if (cryptFlag === DECRYPT) {
|
||
// 解密过程在组解密后进行异或
|
||
_output[_i2] ^= lastVector[_i2];
|
||
}
|
||
}
|
||
|
||
outArray[point + _i2] = _output[_i2];
|
||
}
|
||
|
||
if (mode === 'cbc') {
|
||
if (cryptFlag !== DECRYPT) {
|
||
// 使用上一次输出作为加密向量
|
||
lastVector = _output;
|
||
} else {
|
||
// 使用上一次输入作为解密向量
|
||
lastVector = input;
|
||
}
|
||
}
|
||
|
||
restLen -= BLOCK;
|
||
point += BLOCK;
|
||
}
|
||
|
||
// 去除填充,sm4 是 16 个字节一个分组,所以统一走到 pkcs#7
|
||
if ((padding === 'pkcs#5' || padding === 'pkcs#7') && cryptFlag === DECRYPT) {
|
||
var len = outArray.length;
|
||
var _paddingCount = outArray[len - 1];
|
||
for (var _i3 = 1; _i3 <= _paddingCount; _i3++) {
|
||
if (outArray[len - _i3] !== _paddingCount) throw new Error('padding is invalid');
|
||
}
|
||
outArray.splice(len - _paddingCount, _paddingCount);
|
||
}
|
||
|
||
// 调整输出
|
||
if (output !== 'array') {
|
||
if (cryptFlag !== DECRYPT) {
|
||
// 加密,输出转 16 进制串
|
||
return ArrayToHex(outArray);
|
||
} else {
|
||
// 解密,输出转 utf8 串
|
||
return arrayToUtf8(outArray);
|
||
}
|
||
} else {
|
||
return outArray;
|
||
}
|
||
}
|
||
|
||
module.exports = {
|
||
encrypt: function encrypt(inArray, key, options) {
|
||
return sm4(inArray, key, 1, options);
|
||
},
|
||
decrypt: function decrypt(inArray, key, options) {
|
||
return sm4(inArray, key, 0, options);
|
||
}
|
||
};
|
||
|
||
/***/ })
|
||
/******/ ]); |