This commit is contained in:
2022-07-21 03:28:35 +00:00
parent d7c883d6df
commit 51b34b0e1d
30103 changed files with 4152204 additions and 23 deletions
+67
View File
@@ -0,0 +1,67 @@
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.encodeAsn1Signature = exports.decodeAsn1Signature = void 0;
var _params = _interopRequireDefault(require("./params.js"));
var _asn = _interopRequireDefault(require("asn1.js"));
var _buffer = _interopRequireDefault(require("buffer"));
/**
* asn1enc.js
*/
var Buffer = _buffer.default.Buffer;
var BN = _asn.default.bignum;
/**
* Decode ASN.1 encoded signature byte array.
* @param {Uint8Array} asn1sig - Byte array of ASN.1 encoded signature.
* @param {String} namedCurve - Name of curve like 'P-256'.
* @return {Uint8Array} - Decoded raw signature.
*/
var decodeAsn1Signature = function decodeAsn1Signature(asn1sig, namedCurve) {
var asn1sigBuffer = Buffer.from(asn1sig); // This must be Buffer object to get decoded;
var decoded = ECDSASignature.decode(asn1sigBuffer, 'der');
var len = _params.default.namedCurves[namedCurve].payloadSize;
var r = new Uint8Array(decoded.r.toArray('be', len));
var s = new Uint8Array(decoded.s.toArray('be', len));
var signature = new Uint8Array(len * 2);
signature.set(r);
signature.set(s, len);
return signature;
};
/**
* Encode raw signature and obtain ASN.1-encoded signature.
* @param {Uint8Array} signature - Byte array of raw signature.
* @param {String} namedCurve - Name of curve like 'P-256'.
* @return {Uint8Array} - Encoded ASN.1 signature.
*/
exports.decodeAsn1Signature = decodeAsn1Signature;
var encodeAsn1Signature = function encodeAsn1Signature(signature, namedCurve) {
var len = _params.default.namedCurves[namedCurve].payloadSize;
var r = signature.slice(0, len);
var s = signature.slice(len, signature.length);
var asn1sig = ECDSASignature.encode({
r: new BN(r),
s: new BN(s)
}, 'der');
return new Uint8Array(asn1sig);
}; /////////////////////////////////////////////////////////////////////////////////////////
// RFC5759 https://tools.ietf.org/html/rfc5759.html
exports.encodeAsn1Signature = encodeAsn1Signature;
var ECDSASignature = _asn.default.define('ECDSASignature', function () {
this.seq().obj(this.key('r').int(), this.key('s').int());
});
+456
View File
@@ -0,0 +1,456 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.deriveSecret = exports.verify = exports.sign = exports.generateKey = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var util = _interopRequireWildcard(require("js-crypto-env"));
var webapi = _interopRequireWildcard(require("./webapi.js"));
var nodeapi = _interopRequireWildcard(require("./nodeapi.js"));
var purejs = _interopRequireWildcard(require("./purejs.js"));
/**
* ec.js
*/
/**
* Generate elliptic curve cryptography public/private key pair. Generated keys are in JWK.
* @param {String} [namedCurve='P-256'] - Name of curve like 'P-256'.
* @return {Promise<{publicKey: JsonWebKey, privateKey: JsonWebKey }>} - The generated keys.
* @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works.
*/
var generateKey =
/*#__PURE__*/
function () {
var _ref = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
var namedCurve,
webCrypto,
nodeCrypto,
native,
errMsg,
keyPair,
_args = arguments;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
namedCurve = _args.length > 0 && _args[0] !== undefined ? _args[0] : 'P-256';
webCrypto = util.getWebCrypto(); // web crypto api
nodeCrypto = util.getNodeCrypto(); // implementation on node.js
native = true;
keyPair = {};
if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.generateKey === 'function' && typeof webCrypto.exportKey === 'function')) {
_context.next = 11;
break;
}
_context.next = 8;
return webapi.generateKey(namedCurve, webCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 8:
keyPair = _context.sent;
_context.next = 18;
break;
case 11:
if (!(typeof nodeCrypto !== 'undefined')) {
_context.next = 17;
break;
}
_context.next = 14;
return nodeapi.generateKey(namedCurve, nodeCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 14:
keyPair = _context.sent;
_context.next = 18;
break;
case 17:
native = false;
case 18:
if (!(native === false)) {
_context.next = 22;
break;
}
_context.next = 21;
return purejs.generateKey(namedCurve).catch(function (e) {
errMsg = "".concat(errMsg, " => ").concat(e.message);
throw new Error("UnsupportedEnvironment: ".concat(errMsg));
});
case 21:
keyPair = _context.sent;
case 22:
return _context.abrupt("return", keyPair);
case 23:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function generateKey() {
return _ref.apply(this, arguments);
};
}();
/**
* Sign message with ECDSA.
* @param {Uint8Array} msg - Byte array of message to be signed.
* @param {JsonWebKey} privateJwk - Private key object in JWK format.
* @param {String} [hash='SHA-256'] - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} [signatureFormat='raw'] - Signature format. 'raw' indicates the purely raw byte array of signature. It can also take 'der', and then the output is ASN.1 DER formatted.
* @return {Promise<Uint8Array>} - Output signature byte array in raw or der format.
* @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works.
*/
exports.generateKey = generateKey;
var sign =
/*#__PURE__*/
function () {
var _ref2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(msg, privateJwk) {
var hash,
signatureFormat,
webCrypto,
nodeCrypto,
native,
errMsg,
signature,
_args2 = arguments;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
hash = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : 'SHA-256';
signatureFormat = _args2.length > 3 && _args2[3] !== undefined ? _args2[3] : 'raw';
if (!(signatureFormat !== 'raw' && signatureFormat !== 'der')) {
_context2.next = 4;
break;
}
throw new Error('InvalidSignatureFormat');
case 4:
webCrypto = util.getWebCrypto(); // web crypto api
nodeCrypto = util.getNodeCrypto(); // implementation on node.js
native = true;
if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.sign === 'function')) {
_context2.next = 13;
break;
}
_context2.next = 10;
return webapi.sign(msg, privateJwk, hash, signatureFormat, webCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 10:
signature = _context2.sent;
_context2.next = 20;
break;
case 13:
if (!(typeof nodeCrypto !== 'undefined')) {
_context2.next = 19;
break;
}
_context2.next = 16;
return nodeapi.sign(msg, privateJwk, hash, signatureFormat, nodeCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 16:
signature = _context2.sent;
_context2.next = 20;
break;
case 19:
native = false;
case 20:
if (!(native === false)) {
_context2.next = 24;
break;
}
_context2.next = 23;
return purejs.sign(msg, privateJwk, hash, signatureFormat).catch(function (e) {
errMsg = "".concat(errMsg, " => ").concat(e.message);
throw new Error("UnsupportedEnvironment: ".concat(errMsg));
});
case 23:
signature = _context2.sent;
case 24:
return _context2.abrupt("return", signature);
case 25:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function sign(_x, _x2) {
return _ref2.apply(this, arguments);
};
}();
/**
* Verify signature with ECDSA.
* @param {Uint8Array} msg - Byte array of message that have been signed.
* @param {Uint8Array} signature - Byte array of signature for the given message.
* @param {JsonWebKey} publicJwk - Public key object in JWK format.
* @param {String} [hash='SHA-256'] - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} [signatureFormat='raw'] - Signature format. 'raw' indicates the purely raw byte array of signature. It can also take 'der', and then the input must be in ASN.1 DER format.
* @return {Promise<boolean>} - The result of verification.
* @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works.
*/
exports.sign = sign;
var verify =
/*#__PURE__*/
function () {
var _ref3 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(msg, signature, publicJwk) {
var hash,
signatureFormat,
webCrypto,
nodeCrypto,
native,
errMsg,
valid,
_args3 = arguments;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
hash = _args3.length > 3 && _args3[3] !== undefined ? _args3[3] : 'SHA-256';
signatureFormat = _args3.length > 4 && _args3[4] !== undefined ? _args3[4] : 'raw';
if (!(signatureFormat !== 'raw' && signatureFormat !== 'der')) {
_context3.next = 4;
break;
}
throw new Error('InvalidSignatureFormat');
case 4:
webCrypto = util.getWebCrypto(); // web crypto api
nodeCrypto = util.getNodeCrypto(); // implementation on node.js
native = true;
if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.verify === 'function')) {
_context3.next = 13;
break;
}
_context3.next = 10;
return webapi.verify(msg, signature, publicJwk, hash, signatureFormat, webCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 10:
valid = _context3.sent;
_context3.next = 20;
break;
case 13:
if (!(typeof nodeCrypto !== 'undefined')) {
_context3.next = 19;
break;
}
_context3.next = 16;
return nodeapi.verify(msg, signature, publicJwk, hash, signatureFormat, nodeCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 16:
valid = _context3.sent;
_context3.next = 20;
break;
case 19:
native = false;
case 20:
if (!(native === false)) {
_context3.next = 24;
break;
}
_context3.next = 23;
return purejs.verify(msg, signature, publicJwk, hash, signatureFormat).catch(function (e) {
errMsg = "".concat(errMsg, " => ").concat(e.message);
throw new Error("UnsupportedEnvironment: ".concat(errMsg));
});
case 23:
valid = _context3.sent;
case 24:
return _context3.abrupt("return", valid);
case 25:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function verify(_x3, _x4, _x5) {
return _ref3.apply(this, arguments);
};
}();
/**
* ECDH: Elliptic Curve Diffie-Hellman Key Exchange, which derives shared secret from my private key and destination's public key.
* **NOTE** We SHOULD NOT use the derived secret as an encryption key directly.
* We should employ an appropriate key derivation procedure like HKDF to use the secret for symmetric key encryption.
* @param {JsonWebKey} publicJwk - Remote public key object in JWK format.
* @param {JsonWebKey} privateJwk - Local (my) private key object in JWK format.
* @return {Promise<Uint8Array>} - The derived master secret via ECDH.
* @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works.
*/
exports.verify = verify;
var deriveSecret =
/*#__PURE__*/
function () {
var _ref4 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4(publicJwk, privateJwk) {
var webCrypto, nodeCrypto, native, errMsg, secret;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
if (!(publicJwk.crv !== privateJwk.crv)) {
_context4.next = 2;
break;
}
throw new Error('UnmatchedCurveName');
case 2:
webCrypto = util.getWebCrypto(); // web crypto api
nodeCrypto = util.getNodeCrypto(); // implementation on node.js
native = true;
if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.deriveBits === 'function')) {
_context4.next = 11;
break;
}
_context4.next = 8;
return webapi.deriveSecret(publicJwk, privateJwk, webCrypto).catch(function (e) {
errMsg = e.message;
native = false;
});
case 8:
secret = _context4.sent;
_context4.next = 12;
break;
case 11:
if (typeof nodeCrypto !== 'undefined') {
// for node
try {
secret = nodeapi.deriveSecret(publicJwk, privateJwk, nodeCrypto);
} catch (e) {
errMsg = e.message;
native = false;
}
} else native = false;
case 12:
if (!(native === false)) {
_context4.next = 23;
break;
}
_context4.prev = 13;
_context4.next = 16;
return purejs.deriveSecret(publicJwk, privateJwk);
case 16:
secret = _context4.sent;
_context4.next = 23;
break;
case 19:
_context4.prev = 19;
_context4.t0 = _context4["catch"](13);
errMsg = "".concat(errMsg, " => ").concat(_context4.t0.message);
throw new Error("UnsupportedEnvironment: ".concat(errMsg));
case 23:
return _context4.abrupt("return", secret);
case 24:
case "end":
return _context4.stop();
}
}
}, _callee4, null, [[13, 19]]);
}));
return function deriveSecret(_x6, _x7) {
return _ref4.apply(this, arguments);
};
}();
exports.deriveSecret = deriveSecret;
+43
View File
@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "generateKey", {
enumerable: true,
get: function get() {
return _ec.generateKey;
}
});
Object.defineProperty(exports, "sign", {
enumerable: true,
get: function get() {
return _ec.sign;
}
});
Object.defineProperty(exports, "verify", {
enumerable: true,
get: function get() {
return _ec.verify;
}
});
Object.defineProperty(exports, "deriveSecret", {
enumerable: true,
get: function get() {
return _ec.deriveSecret;
}
});
exports.default = void 0;
var _ec = require("./ec.js");
/**
* index.js
*/
var _default = {
generateKey: _ec.generateKey,
sign: _ec.sign,
verify: _ec.verify,
deriveSecret: _ec.deriveSecret
};
exports.default = _default;
File diff suppressed because one or more lines are too long
+247
View File
@@ -0,0 +1,247 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.deriveSecret = exports.verify = exports.sign = exports.generateKey = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _params = _interopRequireDefault(require("./params.js"));
var asn1enc = _interopRequireWildcard(require("./asn1enc.js"));
var _jsCryptoKeyUtils = require("js-crypto-key-utils");
var _jsEncodingUtils = _interopRequireDefault(require("js-encoding-utils"));
/**
* nodeapi.js
*/
/**
* Generate elliptic curve cryptography public/private key pair. Generated keys are in JWK.
* @param {String} namedCurve - Name of curve like 'P-256'.
* @param {Object} nodeCrypto - NodeCrypto object.
* @return {Promise<{publicKey: JsonWebKey, privateKey: JsonWebKey}>} - The generated keys.
* @throws {Error} - Throws if NotPublic/PrivateKeyForECCKeyGenNode
*/
var generateKey =
/*#__PURE__*/
function () {
var _ref = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee(namedCurve, nodeCrypto) {
var ecdh, publicOct, privateOct, publicKey, publicJwk, privateKey, privateJwk;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
ecdh = nodeCrypto.ECDH(_params.default.namedCurves[namedCurve].nodeName);
ecdh.generateKeys();
publicOct = new Uint8Array(ecdh.getPublicKey());
privateOct = new Uint8Array(ecdh.getPrivateKey());
publicKey = new _jsCryptoKeyUtils.Key('oct', publicOct, {
namedCurve: namedCurve
});
if (!publicKey.isPrivate) {
_context.next = 7;
break;
}
throw new Error('NotPublicKeyForECCKeyGenNode');
case 7:
_context.next = 9;
return publicKey.export('jwk', {
outputPublic: true
});
case 9:
publicJwk = _context.sent;
privateKey = new _jsCryptoKeyUtils.Key('oct', privateOct, {
namedCurve: namedCurve
});
if (privateKey.isPrivate) {
_context.next = 13;
break;
}
throw new Error('NotPrivateKeyForECCKeyGenNode');
case 13:
_context.next = 15;
return privateKey.export('jwk');
case 15:
privateJwk = _context.sent;
return _context.abrupt("return", {
publicKey: publicJwk,
privateKey: privateJwk
});
case 17:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function generateKey(_x, _x2) {
return _ref.apply(this, arguments);
};
}();
/**
* Sign message with ECDSA.
* @param {Uint8Array} msg - Byte array of message to be signed.
* @param {JsonWebKey} privateJwk - Private key object in JWK format.
* @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} signatureFormat - Signature format, 'raw' or 'der'
* @param {Object} nodeCrypto - NodeCrypto object.
* @return {Promise<Uint8Array>} - Output signature byte array in raw or der format.
* @throws {Error} - Throws if NotPrivateKeyForECCSignNode.
*/
exports.generateKey = generateKey;
var sign =
/*#__PURE__*/
function () {
var _ref2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(msg, privateJwk, hash, signatureFormat, nodeCrypto) {
var privateKey, privatePem, sign, asn1sig;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
privateKey = new _jsCryptoKeyUtils.Key('jwk', privateJwk);
if (privateKey.isPrivate) {
_context2.next = 3;
break;
}
throw new Error('NotPrivateKeyForECCSignNode');
case 3:
_context2.next = 5;
return privateKey.export('pem');
case 5:
privatePem = _context2.sent;
sign = nodeCrypto.createSign(_params.default.hashes[hash].nodeName);
sign.update(msg);
asn1sig = sign.sign(privatePem);
return _context2.abrupt("return", signatureFormat === 'raw' ? asn1enc.decodeAsn1Signature(asn1sig, privateJwk.crv) : asn1sig);
case 10:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function sign(_x3, _x4, _x5, _x6, _x7) {
return _ref2.apply(this, arguments);
};
}();
/**
* Verify signature with ECDSA.
* @param {Uint8Array} msg - Byte array of message that have been signed.
* @param {Uint8Array} signature - Byte array of signature for the given message.
* @param {JsonWebKey} publicJwk - Public key object in JWK format.
* @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} signatureFormat - Signature format,'raw' or 'der'.
* @param {Object} nodeCrypto - NodeCrypto object.
* @return {Promise<boolean>} - The result of verification.
* @throws {Error} - Throws if NotPublicKeyForEccVerifyNode.
*/
exports.sign = sign;
var verify =
/*#__PURE__*/
function () {
var _ref3 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(msg, signature, publicJwk, hash, signatureFormat, nodeCrypto) {
var publicKey, publicPem, verify, asn1sig;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
publicKey = new _jsCryptoKeyUtils.Key('jwk', publicJwk);
if (publicKey.isPrivate) {
_context3.next = 3;
break;
}
throw new Error('NotPrivateKeyForECCVerifyNode');
case 3:
_context3.next = 5;
return publicKey.export('pem', {
outputPublic: true,
compact: false
});
case 5:
publicPem = _context3.sent;
verify = nodeCrypto.createVerify(_params.default.hashes[hash].nodeName);
verify.update(msg);
asn1sig = signatureFormat === 'raw' ? asn1enc.encodeAsn1Signature(signature, publicJwk.crv) : signature;
return _context3.abrupt("return", verify.verify(publicPem, asn1sig));
case 10:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function verify(_x8, _x9, _x10, _x11, _x12, _x13) {
return _ref3.apply(this, arguments);
};
}();
/**
* Key Derivation for ECDH, Elliptic Curve Diffie-Hellman Key Exchange.
* @param {JsonWebKey} publicJwk - Remote public key object in JWK format.
* @param {JsonWebKey} privateJwk - Local (my) private key object in JWK format.
* @param {Object} nodeCrypto - NodeCrypto object.
* @return {Uint8Array} - The derived master secret via ECDH.
*/
exports.verify = verify;
var deriveSecret = function deriveSecret(publicJwk, privateJwk, nodeCrypto) {
var curve = _params.default.namedCurves[privateJwk.crv].nodeName;
var payloadSize = _params.default.namedCurves[privateJwk.crv].payloadSize;
var ecdh = nodeCrypto.createECDH(curve);
var privKeyBuf = _jsEncodingUtils.default.encoder.decodeBase64Url(privateJwk.d);
var pubKeyBuf = new Uint8Array(payloadSize * 2 + 1);
pubKeyBuf[0] = 0xFF & 0x04;
pubKeyBuf.set(_jsEncodingUtils.default.encoder.decodeBase64Url(publicJwk.x), 1);
pubKeyBuf.set(_jsEncodingUtils.default.encoder.decodeBase64Url(publicJwk.y), payloadSize + 1);
ecdh.setPrivateKey(privKeyBuf);
return new Uint8Array(ecdh.computeSecret(pubKeyBuf));
};
exports.deriveSecret = deriveSecret;
+53
View File
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/**
* params.js
*/
var _default = {
namedCurves: {
'P-256': {
indutnyName: 'p256',
nodeName: 'prime256v1',
payloadSize: 32
},
'P-384': {
indutnyName: 'p384',
nodeName: 'secp384r1',
payloadSize: 48
},
'P-521': {
indutnyName: 'p521',
nodeName: 'secp521r1',
payloadSize: 66
},
'P-256K': {
indutnyName: 'secp256k1',
nodeName: 'secp256k1',
payloadSize: 32
}
},
hashes: {
'SHA-256': {
nodeName: 'sha256'
},
//, hashSize: 32},
'SHA-384': {
nodeName: 'sha384'
},
//, hashSize: 48},
'SHA-512': {
nodeName: 'sha512'
},
//, hashSize: 64}
'SHA-1': {
nodeName: 'sha1'
} //, hashSize: 20},
}
};
exports.default = _default;
+351
View File
@@ -0,0 +1,351 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.deriveSecret = exports.verify = exports.sign = exports.generateKey = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _params = _interopRequireDefault(require("./params.js"));
var asn1enc = _interopRequireWildcard(require("./asn1enc.js"));
var _jsCryptoRandom = _interopRequireDefault(require("js-crypto-random"));
var _jsCryptoHash = _interopRequireDefault(require("js-crypto-hash"));
var _jsCryptoKeyUtils = require("js-crypto-key-utils");
var _jsEncodingUtils = _interopRequireDefault(require("js-encoding-utils"));
var _elliptic = _interopRequireDefault(require("elliptic"));
/**
* purejs.js
*/
var Ec = _elliptic.default.ec;
/**
* Generate elliptic curve cryptography public/private key pair. Generated keys are in JWK.
* @param {String} namedCurve - Name of curve like 'P-256'.
* @return {Promise<{publicKey: JsonWebKey, privateKey: JsonWebKey}>} - The generated keys.
* @throws {Error} - Throws if NotPublic/PrivateKeyForECCKeyGenPureJS
*/
var generateKey =
/*#__PURE__*/
function () {
var _ref = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee(namedCurve) {
var curve, ec, ecKey, len, publicOct, privateOct, publicKey, publicJwk, privateKey, privateJwk;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
curve = _params.default.namedCurves[namedCurve].indutnyName;
ec = new Ec(curve);
_context.t0 = ec;
_context.t1 = _jsEncodingUtils.default.encoder;
_context.next = 6;
return _jsCryptoRandom.default.getRandomBytes(32);
case 6:
_context.t2 = _context.sent;
_context.t3 = _context.t1.arrayBufferToString.call(_context.t1, _context.t2);
_context.t4 = {
entropy: _context.t3
};
ecKey = _context.t0.genKeyPair.call(_context.t0, _context.t4);
len = _params.default.namedCurves[namedCurve].payloadSize;
publicOct = new Uint8Array(ecKey.getPublic('array'));
privateOct = new Uint8Array(ecKey.getPrivate().toArray('be', len));
publicKey = new _jsCryptoKeyUtils.Key('oct', publicOct, {
namedCurve: namedCurve
});
if (!publicKey.isPrivate) {
_context.next = 16;
break;
}
throw new Error('NotPublicKeyForECCKeyGenPureJS');
case 16:
_context.next = 18;
return publicKey.export('jwk', {
outputPublic: true
});
case 18:
publicJwk = _context.sent;
privateKey = new _jsCryptoKeyUtils.Key('oct', privateOct, {
namedCurve: namedCurve
});
if (privateKey.isPrivate) {
_context.next = 22;
break;
}
throw new Error('NotPrivateKeyForECCKeyGenPureJS');
case 22:
_context.next = 24;
return privateKey.export('jwk');
case 24:
privateJwk = _context.sent;
return _context.abrupt("return", {
publicKey: publicJwk,
privateKey: privateJwk
});
case 26:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function generateKey(_x) {
return _ref.apply(this, arguments);
};
}();
/**
* Sign message with ECDSA.
* @param {Uint8Array} msg - Byte array of message to be signed.
* @param {JsonWebKey} privateJwk - Private key object in JWK format.
* @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} signatureFormat - Signature format, 'raw' or 'der'
* @return {Promise<Uint8Array>} - Output signature byte array in raw or der format.
* @throws {Error} - Throws if NotPrivateKeyForECCSIgnPureJS
*/
exports.generateKey = generateKey;
var sign =
/*#__PURE__*/
function () {
var _ref2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(msg, privateJwk, hash, signatureFormat) {
var namedCurve, curve, ec, privateKey, privateOct, ecKey, md, signature, len, arrayR, arrayS, concat;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
namedCurve = privateJwk.crv;
curve = _params.default.namedCurves[namedCurve].indutnyName;
ec = new Ec(curve);
privateKey = new _jsCryptoKeyUtils.Key('jwk', privateJwk);
if (privateKey.isPrivate) {
_context2.next = 6;
break;
}
throw new Error('NotPrivateKeyForECCSignPureJS');
case 6:
_context2.next = 8;
return privateKey.export('oct');
case 8:
privateOct = _context2.sent;
ecKey = ec.keyFromPrivate(privateOct); // get hash
_context2.next = 12;
return _jsCryptoHash.default.compute(msg, hash);
case 12:
md = _context2.sent;
// generate signature
signature = ecKey.sign(md); // formatting
len = _params.default.namedCurves[namedCurve].payloadSize;
arrayR = new Uint8Array(signature.r.toArray('be', len));
arrayS = new Uint8Array(signature.s.toArray('be', len));
concat = new Uint8Array(arrayR.length + arrayS.length);
concat.set(arrayR);
concat.set(arrayS, arrayR.length);
return _context2.abrupt("return", signatureFormat === 'raw' ? concat : asn1enc.encodeAsn1Signature(concat, namedCurve));
case 21:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function sign(_x2, _x3, _x4, _x5) {
return _ref2.apply(this, arguments);
};
}();
/**
* Verify signature with ECDSA.
* @param {Uint8Array} msg - Byte array of message that have been signed.
* @param {Uint8Array} signature - Byte array of signature for the given message.
* @param {JsonWebKey} publicJwk - Public key object in JWK format.
* @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} signatureFormat - Signature format,'raw' or 'der'.
* @return {Promise<boolean>} - The result of verification.
* @throws {Error} - Throws if NotPublicKeyForEccVerifyPureJS.
*/
exports.sign = sign;
var verify =
/*#__PURE__*/
function () {
var _ref3 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(msg, signature, publicJwk, hash, signatureFormat) {
var namedCurve, curve, ec, publicKey, publicOct, ecKey, len, sigR, sigS, md;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
namedCurve = publicJwk.crv;
curve = _params.default.namedCurves[namedCurve].indutnyName;
ec = new Ec(curve);
publicKey = new _jsCryptoKeyUtils.Key('jwk', publicJwk);
if (!publicKey.isPrivate) {
_context3.next = 6;
break;
}
throw new Error('NotPublicKeyForECCVerifyPureJS');
case 6:
_context3.next = 8;
return publicKey.export('oct', {
compact: false,
outputPublic: true
});
case 8:
publicOct = _context3.sent;
ecKey = ec.keyFromPublic(publicOct); // parse signature
len = _params.default.namedCurves[namedCurve].payloadSize;
if (!(signature instanceof Uint8Array)) signature = new Uint8Array(signature);
signature = signatureFormat === 'raw' ? signature : asn1enc.decodeAsn1Signature(signature, namedCurve);
sigR = signature.slice(0, len);
sigS = signature.slice(len, len + sigR.length); // get hash
_context3.next = 17;
return _jsCryptoHash.default.compute(msg, hash);
case 17:
md = _context3.sent;
_context3.next = 20;
return ecKey.verify(md, {
s: sigS,
r: sigR
});
case 20:
return _context3.abrupt("return", _context3.sent);
case 21:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function verify(_x6, _x7, _x8, _x9, _x10) {
return _ref3.apply(this, arguments);
};
}();
/**
* Key Derivation for ECDH, Elliptic Curve Diffie-Hellman Key Exchange.
* @param {JsonWebKey} publicJwk - Remote public key object in JWK format.
* @param {JsonWebKey} privateJwk - Local (my) private key object in JWK format.
* @return {Promise<Uint8Array>} - The derived master secret via ECDH.
* @throws {Error} - Throws if NotPublic/PrivateKeyForECCSDeriveKeyPureJS.
*/
exports.verify = verify;
var deriveSecret =
/*#__PURE__*/
function () {
var _ref4 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4(publicJwk, privateJwk) {
var namedCurve, curve, ec, priKeyObj, privateOct, pubKeyObj, publicOct, privateKey, publicKey, len;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
namedCurve = privateJwk.crv;
curve = _params.default.namedCurves[namedCurve].indutnyName;
ec = new Ec(curve);
priKeyObj = new _jsCryptoKeyUtils.Key('jwk', privateJwk);
if (priKeyObj.isPrivate) {
_context4.next = 6;
break;
}
throw new Error('NotPrivateKeyForECCSDeriveKeyPureJS');
case 6:
_context4.next = 8;
return priKeyObj.export('oct');
case 8:
privateOct = _context4.sent;
pubKeyObj = new _jsCryptoKeyUtils.Key('jwk', publicJwk);
if (!pubKeyObj.isPrivate) {
_context4.next = 12;
break;
}
throw new Error('NotPublicKeyForECCDeriveKeyPureJS');
case 12:
_context4.next = 14;
return pubKeyObj.export('oct', {
compact: false,
outputPublic: true
});
case 14:
publicOct = _context4.sent;
privateKey = ec.keyFromPrivate(privateOct);
publicKey = ec.keyFromPublic(publicOct); // derive shared key
len = _params.default.namedCurves[namedCurve].payloadSize;
return _context4.abrupt("return", new Uint8Array(privateKey.derive(publicKey.getPublic()).toArray('be', len)));
case 19:
case "end":
return _context4.stop();
}
}
}, _callee4);
}));
return function deriveSecret(_x11, _x12) {
return _ref4.apply(this, arguments);
};
}();
exports.deriveSecret = deriveSecret;
+261
View File
@@ -0,0 +1,261 @@
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.deriveSecret = exports.verify = exports.sign = exports.generateKey = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _jsEncodingUtils = _interopRequireDefault(require("js-encoding-utils"));
var asn1enc = _interopRequireWildcard(require("./asn1enc.js"));
/**
* webapi.js
*/
/**
* Generate elliptic curve cryptography public/private key pair. Generated keys are in JWK.
* @param {String} namedCurve - Name of curve like 'P-256'.
* @param {Object} webCrypto - WebCryptoSubtle object.
* @return {Promise<{publicKey: JsonWebKey, privateKey: JsonWebKey}>} - The generated keys.
*/
var generateKey =
/*#__PURE__*/
function () {
var _ref = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee(namedCurve, webCrypto) {
var keys, publicKey, privateKey;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return webCrypto.generateKey({
name: 'ECDSA',
namedCurve: namedCurve,
hash: {
name: 'SHA-256'
}
}, true, ['sign', 'verify']);
case 2:
keys = _context.sent;
_context.next = 5;
return webCrypto.exportKey('jwk', keys.publicKey);
case 5:
publicKey = _context.sent;
_context.next = 8;
return webCrypto.exportKey('jwk', keys.privateKey);
case 8:
privateKey = _context.sent;
// delete optional entries to export as general ecdsa/ecdh key
['key_ops', 'alg', 'ext'].forEach(function (elem) {
delete publicKey[elem];
delete privateKey[elem];
});
return _context.abrupt("return", {
publicKey: publicKey,
privateKey: privateKey
});
case 11:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function generateKey(_x, _x2) {
return _ref.apply(this, arguments);
};
}();
/**
* Sign message with ECDSA.
* @param {Uint8Array} msg - Byte array of message to be signed.
* @param {JsonWebKey} privateJwk - Private key object in JWK format.
* @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} signatureFormat - Signature format, 'raw' or 'der'
* @param {Object} webCrypto - WebCryptoSubtle object.
* @return {Promise<Uint8Array>} - Output signature byte array in raw or der format.
*/
exports.generateKey = generateKey;
var sign =
/*#__PURE__*/
function () {
var _ref2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(msg, privateJwk, hash, signatureFormat, webCrypto) {
var algo, key, signature;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
algo = {
name: 'ECDSA',
namedCurve: privateJwk.crv,
hash: {
name: hash
}
};
_context2.next = 3;
return webCrypto.importKey('jwk', privateJwk, algo, false, ['sign']);
case 3:
key = _context2.sent;
_context2.next = 6;
return webCrypto.sign(algo, key, msg);
case 6:
signature = _context2.sent;
return _context2.abrupt("return", signatureFormat === 'raw' ? new Uint8Array(signature) : asn1enc.encodeAsn1Signature(new Uint8Array(signature), privateJwk.crv));
case 8:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function sign(_x3, _x4, _x5, _x6, _x7) {
return _ref2.apply(this, arguments);
};
}();
/**
* Verify signature with ECDSA.
* @param {Uint8Array} msg - Byte array of message that have been signed.
* @param {Uint8Array} signature - Byte array of signature for the given message.
* @param {JsonWebKey} publicJwk - Public key object in JWK format.
* @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'.
* @param {String} signatureFormat - Signature format,'raw' or 'der'.
* @param {Object} webCrypto - WebCryptoSubtle object.
* @return {Promise<boolean>} - The result of verification.
*/
exports.sign = sign;
var verify =
/*#__PURE__*/
function () {
var _ref3 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(msg, signature, publicJwk, hash, signatureFormat, webCrypto) {
var algo, key, rawSignature;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
algo = {
name: 'ECDSA',
namedCurve: publicJwk.crv,
hash: {
name: hash
}
};
_context3.next = 3;
return webCrypto.importKey('jwk', publicJwk, algo, false, ['verify']);
case 3:
key = _context3.sent;
rawSignature = signatureFormat === 'raw' ? signature : asn1enc.decodeAsn1Signature(signature, publicJwk.crv);
_context3.next = 7;
return webCrypto.verify(algo, key, rawSignature, msg);
case 7:
return _context3.abrupt("return", _context3.sent);
case 8:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function verify(_x8, _x9, _x10, _x11, _x12, _x13) {
return _ref3.apply(this, arguments);
};
}();
/**
* Key Derivation for ECDH, Elliptic Curve Diffie-Hellman Key Exchange.
* @param {JsonWebKey} publicJwk - Remote public key object in JWK format.
* @param {JsonWebKey} privateJwk - Local (my) private key object in JWK format.
* @param {Object} webCrypto - WebCryptoSubtle object.
* @return {Promise<Uint8Array>} - The derived master secret via ECDH.
*/
exports.verify = verify;
var deriveSecret =
/*#__PURE__*/
function () {
var _ref4 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4(publicJwk, privateJwk, webCrypto) {
var algo, privateKey, publicKey, bitLen;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
algo = {
name: 'ECDH',
namedCurve: privateJwk.crv
};
_context4.next = 3;
return webCrypto.importKey('jwk', privateJwk, algo, false, ['deriveBits']);
case 3:
privateKey = _context4.sent;
_context4.next = 6;
return webCrypto.importKey('jwk', publicJwk, algo, false, []);
case 6:
publicKey = _context4.sent;
bitLen = function bitLen() {
var arr = _jsEncodingUtils.default.encoder.decodeBase64Url(privateJwk.x);
return 8 * arr.length;
};
_context4.t0 = Uint8Array;
_context4.next = 11;
return webCrypto.deriveBits(Object.assign(algo, {
public: publicKey
}), privateKey, bitLen());
case 11:
_context4.t1 = _context4.sent;
return _context4.abrupt("return", new _context4.t0(_context4.t1));
case 13:
case "end":
return _context4.stop();
}
}
}, _callee4);
}));
return function deriveSecret(_x14, _x15, _x16) {
return _ref4.apply(this, arguments);
};
}();
exports.deriveSecret = deriveSecret;