@guarani/jose
Version:
Implementation of the RFCs of the JOSE Working Group.
78 lines (77 loc) • 3.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.A256KW = exports.A192KW = exports.A128KW = void 0;
const crypto_1 = require("crypto");
const invalid_json_web_key_exception_1 = require("../../../exceptions/invalid-json-web-key.exception");
const jsonwebencryption_keywrap_algorithm_1 = require("./jsonwebencryption-keywrap.algorithm");
/**
* Implementation of the AES JSON Web Encryption Key Wrap Algorithm.
*/
class AESKeyWrapAlgorithm extends jsonwebencryption_keywrap_algorithm_1.JsonWebEncryptionKeyWrapAlgorithm {
/**
* Instantiates a new JSON Web Encryption AES Key Wrap Algorithm to Wrap and Unwrap Content Encryption Keys.
*
* @param algorithm Name of the JSON Web Encryption Key Wrap Algorithm.
*/
constructor(algorithm) {
super(algorithm, 'oct');
this.keySize = Number.parseInt(this.algorithm.substring(1, 4));
this.cipherAlgorithm = `aes${this.keySize}-wrap`;
}
/**
* Wraps the provided Content Encryption Key using the provide JSON Web Key.
*
* @param enc JSON Web Encryption Content Encryption Algorithm.
* @param key JSON Web Key used to Wrap the provided Content Encryption Key.
* @returns Wrapped Content Encryption Key and optional additional JSON Web Encryption Header Parameters.
*/
async wrap(enc, key) {
this.validateJsonWebKey(key);
const cryptoKey = Reflect.get(key, 'cryptoKey');
const cipher = (0, crypto_1.createCipheriv)(this.cipherAlgorithm, cryptoKey, Buffer.alloc(8, 0xa6));
const cek = await enc.generateContentEncryptionKey();
const ek = Buffer.concat([cipher.update(cek), cipher.final()]);
return { cek, ek };
}
/**
* Unwraps the provided Encrypted Key using the provided JSON Web Key.
*
* @param enc JSON Web Encryption Content Encryption Algorithm.
* @param key JSON Web Key used to Unwrap the Wrapped Content Encryption Key.
* @param ek Wrapped Content Encryption Key.
* @returns Unwrapped Content Encryption Key.
*/
async unwrap(enc, key, ek) {
this.validateJsonWebKey(key);
const cryptoKey = Reflect.get(key, 'cryptoKey');
const decipher = (0, crypto_1.createDecipheriv)(this.cipherAlgorithm, cryptoKey, Buffer.alloc(8, 0xa6));
const cek = Buffer.concat([decipher.update(ek), decipher.final()]);
enc.validateContentEncryptionKey(cek);
return cek;
}
/**
* Checks if the provided JSON Web Key can be used by the requesting JSON Web Encryption AES Key Wrap Algorithm.
*
* @param key JSON Web Key to be checked.
* @throws {InvalidJsonWebKeyException} The provided JSON Web Key is invalid.
*/
validateJsonWebKey(key) {
super.validateJsonWebKey(key);
const exportedKey = key.export({ encoding: 'buffer' });
if (exportedKey.length * 8 !== this.keySize) {
throw new invalid_json_web_key_exception_1.InvalidJsonWebKeyException('Invalid JSON Web Key Secret Size.');
}
}
}
/**
* AES Key Wrap with default initial value using 128-bit key.
*/
exports.A128KW = new AESKeyWrapAlgorithm('A128KW');
/**
* AES Key Wrap with default initial value using 192-bit key.
*/
exports.A192KW = new AESKeyWrapAlgorithm('A192KW');
/**
* AES Key Wrap with default initial value using 256-bit key.
*/
exports.A256KW = new AESKeyWrapAlgorithm('A256KW');