@unvision/jose
Version:
Implementation of the RFCs of the JOSE Working Group.
98 lines • 4.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.A256GCMKW = exports.A192GCMKW = exports.A128GCMKW = void 0;
const crypto_1 = require("crypto");
const util_1 = require("util");
const invalid_jsonwebkey_exception_1 = require("../../../exceptions/invalid-jsonwebkey.exception");
const jsonwebencryption_key_wrap_algorithm_1 = require("./jsonwebencryption-key-wrap.algorithm");
const randomBytesAsync = (0, util_1.promisify)(crypto_1.randomBytes);
/**
* Implementation of the JSON Web Encryption AES-GCM Key Wrap Algorithm.
*
* @see https://www.rfc-editor.org/rfc/rfc7518.html#section-4.7
*/
class GcmAlgorithm extends jsonwebencryption_key_wrap_algorithm_1.JsonWebEncryptionKeyWrapAlgorithm {
/**
* Instantiates a new JSON Web Encryption AES-GCM 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');
/**
* Size of the Initialization Vector in bits.
*/
this.ivSize = 96;
/**
* Size of the Authentication Tag in bytes.
*/
this.authTagLength = 16;
this.keySize = Number.parseInt(this.algorithm.substring(1, 4));
this.cipher = `aes-${this.keySize}-gcm`;
}
/**
* 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 iv = await randomBytesAsync(this.ivSize / 8);
const cryptoKey = key['cryptoKey'];
const cipher = (0, crypto_1.createCipheriv)(this.cipher, cryptoKey, iv, { authTagLength: this.authTagLength });
cipher.setAAD(Buffer.alloc(0));
const cek = await enc.generateContentEncryptionKey();
const ek = Buffer.concat([cipher.update(cek), cipher.final()]);
const tag = cipher.getAuthTag();
return [cek, ek, { iv: iv.toString('base64url'), tag: tag.toString('base64url') }];
}
/**
* 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.
* @param header JSON Web Encryption Header containing the additional Parameters.
* @returns Unwrapped Content Encryption Key.
*/
async unwrap(enc, key, ek, header) {
this.validateJsonWebKey(key);
const iv = Buffer.from(header.iv, 'base64url');
const tag = Buffer.from(header.tag, 'base64url');
const cryptoKey = key['cryptoKey'];
const decipher = (0, crypto_1.createDecipheriv)(this.cipher, cryptoKey, iv, { authTagLength: this.authTagLength });
decipher.setAAD(Buffer.alloc(0));
decipher.setAuthTag(tag);
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-GCM 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['cryptoKey'].export();
if (exportedKey.length * 8 !== this.keySize) {
throw new invalid_jsonwebkey_exception_1.InvalidJsonWebKeyException('Invalid JSON Web Key Secret Size.');
}
}
}
/**
* Key wrapping with AES GCM using 128-bit key.
*/
exports.A128GCMKW = new GcmAlgorithm('A128GCMKW');
/**
* Key wrapping with AES GCM using 192-bit key.
*/
exports.A192GCMKW = new GcmAlgorithm('A192GCMKW');
/**
* Key wrapping with AES GCM using 256-bit key.
*/
exports.A256GCMKW = new GcmAlgorithm('A256GCMKW');
//# sourceMappingURL=gcm.algorithm.js.map