js-crypto-aes
Version:
Universal Module for AES Encryption and Decryption in JavaScript
168 lines • 6.8 kB
JavaScript
"use strict";
/**
* nodeapi.js
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.decrypt = exports.encrypt = exports.unwrapKey = exports.wrapKey = void 0;
var params_1 = __importDefault(require("./params"));
/**
* Node.js KeyWrapping function simply uses encrypt function.
* @param keyToBeWrapped {Uint8Array} - plaintext key
* @param wrappingKey {Uint8Array} - wrapping key
* @param name {string} - 'AES-KW'
* @param iv {Uint8Array} - default is '0xA6A6A6A6A6A6A6A6'
* @param nodeCrypto {Object} - NodeCrypto object
* @return {Uint8Array} - Unwrapped Key
*/
var wrapKey = function (keyToBeWrapped, wrappingKey, _a, nodeCrypto) {
var name = _a.name, iv = _a.iv;
return (0, exports.encrypt)(keyToBeWrapped, wrappingKey, { name: name, iv: iv }, nodeCrypto, true);
};
exports.wrapKey = wrapKey;
/**
* Node.js KeyUnwrapping function as well as keyWrapping
* @param wrappedKey {Uint8Array} - Wrapped key
* @param unwrappingKey {Uint8Array} - Key used for wrapping
* @param name {string} - 'AES-KW'
* @param iv {Uint8Array} - default is '0xA6A6A6A6A6A6A6A6'
* @param nodeCrypto {Object} - NodeCrypto object
* @return {Uint8Array} - Unwrapped Key
*/
var unwrapKey = function (wrappedKey, unwrappingKey, _a, nodeCrypto) {
var name = _a.name, iv = _a.iv;
return (0, exports.decrypt)(wrappedKey, unwrappingKey, { name: name, iv: iv }, nodeCrypto, true);
};
exports.unwrapKey = unwrapKey;
/**
* Encrypt plaintext message via AES Node.js crypto API
* @param {Uint8Array} msg - Plaintext message to be encrypted.
* @param {Uint8Array} key - Byte array of symmetric key.
* @param {String} name - Name of AES algorithm like 'AES-GCM'.
* @param {Uint8Array} [iv] - Byte array of initial vector if required.
* @param {Uint8Array} [additionalData] - Byte array of additional data if required.
* @param {Number} [tagLength] - Authentication tag length if required.
* @param {Object} nodeCrypto - NodeCrypto object, i.e., require(crypto) in Node.js.
* @param wrapKey {Boolean} [false] - true if called as AES-KW
* @return {Uint8Array} - Encrypted message byte array.
* @throws {Error} - Throws error if UnsupportedCipher.
*/
var encrypt = function (msg, key, _a, nodeCrypto, wrapKey) {
var name = _a.name, iv = _a.iv, additionalData = _a.additionalData, tagLength = _a.tagLength;
if (wrapKey === void 0) { wrapKey = false; }
var alg = getNodeName(name, key.byteLength, (wrapKey) ? params_1.default.wrapKeys : params_1.default.ciphers);
var cipher;
switch (name) {
case 'AES-GCM': {
cipher = nodeCrypto.createCipheriv(alg, key, iv, { authTagLength: tagLength });
cipher.setAAD(additionalData);
break;
}
case 'AES-CTR': {
if (iv.length === 0 || iv.length > 16)
throw new Error('InvalidIVLength');
var counter = new Uint8Array(16);
counter.set(iv);
counter[15] += 1;
cipher = nodeCrypto.createCipheriv(alg, key, counter);
break;
}
default: { // AES-CBC or AES-KW
cipher = nodeCrypto.createCipheriv(alg, key, iv);
break;
}
}
var body;
var final;
var tag;
try {
body = new Uint8Array(cipher.update(msg));
final = new Uint8Array(cipher.final());
tag = new Uint8Array([]);
if (name === 'AES-GCM')
tag = new Uint8Array(cipher.getAuthTag());
}
catch (e) {
throw new Error('NodeCrypto_EncryptionFailure');
}
var data = new Uint8Array(body.length + final.length + tag.length);
data.set(body);
data.set(final, body.length);
data.set(tag, body.length + final.length);
return data;
};
exports.encrypt = encrypt;
/**
* Decrypt data through AES Node.js crypto API.
* @param {Uint8Array} data - Encrypted message to be decrypted.
* @param {Uint8Array} key - Byte array of symmetric key.
* @param {String} name - Name of AES algorithm like 'AES-GCM'.
* @param {Uint8Array} [iv] - Byte array of initial vector if required.
* @param {Uint8Array} [additionalData] - Byte array of additional data if required.
* @param {Number} [tagLength] - Authentication tag length if required.
* @param {Object} nodeCrypto - NodeCrypto object, i.e., require(crypto) in Node.js.
* @return {Uint8Array} - Decrypted message byte array.
* @param unwrapKey {Boolean} [false] - true if called as AES-KW
* @throws {Error} - Throws error if UnsupportedCipher or DecryptionFailure.
*/
var decrypt = function (data, key, _a, nodeCrypto, unwrapKey) {
var name = _a.name, iv = _a.iv, additionalData = _a.additionalData, tagLength = _a.tagLength;
if (unwrapKey === void 0) { unwrapKey = false; }
var alg = getNodeName(name, key.byteLength, (unwrapKey) ? params_1.default.wrapKeys : params_1.default.ciphers);
var decipher;
var body;
switch (name) {
case 'AES-GCM': {
decipher = nodeCrypto.createDecipheriv(alg, key, iv, { authTagLength: tagLength });
decipher.setAAD(additionalData);
body = data.slice(0, data.length - tagLength);
var tag = data.slice(data.length - tagLength);
decipher.setAuthTag(tag);
break;
}
case 'AES-CTR': {
if (iv.length === 0 || iv.length > 16)
throw new Error('InvalidIVLength');
var counter = new Uint8Array(16);
counter.set(iv);
counter[15] += 1;
decipher = nodeCrypto.createDecipheriv(alg, key, counter);
body = data;
break;
}
default: { // AES-CBC or AES-KW
decipher = nodeCrypto.createDecipheriv(alg, key, iv);
body = data;
break;
}
}
var decryptedBody;
var final;
try {
decryptedBody = decipher.update(body);
final = decipher.final();
}
catch (e) {
throw new Error('NodeCrypto_DecryptionFailure');
}
var msg = new Uint8Array(final.length + decryptedBody.length);
msg.set(decryptedBody);
msg.set(final, decryptedBody.length);
return msg;
};
exports.decrypt = decrypt;
/**
* get node algorithm name
* @param name {string} - name of webcrypto alg like AES-GCM
* @param keyLength {number} - aes encryption key
* @param dict {object} - params.ciphers or params.wrapKeys
* @return {string} - node algorithm name
*/
var getNodeName = function (name, keyLength, dict) {
var alg = dict[name].nodePrefix;
alg = "".concat(alg).concat((keyLength * 8).toString());
return alg + dict[name].nodeSuffix;
};
//# sourceMappingURL=nodeapi.js.map