UNPKG

@unvision/jose

Version:

Implementation of the RFCs of the JOSE Working Group.

112 lines 5.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.A256CBC_HS512 = exports.A192CBC_HS384 = exports.A128CBC_HS256 = void 0; const crypto_1 = require("crypto"); const invalid_jsonwebencryption_exception_1 = require("../../../exceptions/invalid-jsonwebencryption.exception"); const jose_exception_1 = require("../../../exceptions/jose.exception"); const jsonwebencryption_content_encryption_algorithm_1 = require("./jsonwebencryption-content-encryption.algorithm"); /** * Implementation of the AES-CBC JSON Web Encryption Content Encryption Algorithm. * * @see https://www.rfc-editor.org/rfc/rfc7518.html#section-5.2 */ class CbcAlgorithm extends jsonwebencryption_content_encryption_algorithm_1.JsonWebEncryptionContentEncryptionAlgorithm { /** * Instantiates a new AES-CBC JSON Web Encryption Content Encryption to Encrypt and Decrypt a Plaintext. * * @param algorithm Name of the JSON Web Encryption Content Encryption Algorithm. */ constructor(algorithm) { const regex = /^A([0-9]{3})CBC-HS([0-9]{3})$/; const [keySize, hashSize] = (regex.exec(algorithm).slice(1).map((value) => Number.parseInt(value))); super(algorithm, keySize * 2, 128); this.keySize = keySize; this.hash = `SHA${hashSize}`; this.cipher = `aes-${keySize}-cbc`; } /** * Encrypts the provided Plaintext. * * @param plaintext Plaintext to be Encrypted. * @param aad Additional Authenticated Data. * @param iv Initialization Vector. * @param key Content Encryption Key used to Encrypt the provided Plaintext. * @returns Resulting Ciphertext and Authentication Tag. */ async encrypt(plaintext, aad, iv, key) { try { this.validateInitializationVector(iv); this.validateContentEncryptionKey(key); const macKey = key.subarray(0, this.keySize >> 3); const encKey = key.subarray(this.keySize >> 3); const cipher = (0, crypto_1.createCipheriv)(this.cipher, encKey, iv); const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]); const tag = this.getAuthTag(ciphertext, iv, aad, macKey); return [ciphertext, tag]; } catch (exc) { throw exc instanceof jose_exception_1.JoseException ? exc : new invalid_jsonwebencryption_exception_1.InvalidJsonWebEncryptionException(null, exc); } } /** * Decrypts the provided Ciphertext back to its original Plaintext. * * @param ciphertext Ciphertext to be Decrypted. * @param aad Additional Authenticated Data. * @param iv Initialization Vector. * @param tag Authentication Tag. * @param key Content Encryption Key used to Decrypt the provided Ciphertext. * @returns Resulting Plaintext. */ async decrypt(ciphertext, aad, iv, tag, key) { try { this.validateInitializationVector(iv); this.validateContentEncryptionKey(key); const macKey = key.subarray(0, this.keySize >> 3); const encKey = key.subarray(this.keySize >> 3); const expectedTag = this.getAuthTag(ciphertext, iv, aad, macKey); if (tag.length !== expectedTag.length || !(0, crypto_1.timingSafeEqual)(tag, expectedTag)) { throw new invalid_jsonwebencryption_exception_1.InvalidJsonWebEncryptionException(); } const decipher = (0, crypto_1.createDecipheriv)(this.cipher, encKey, iv); const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]); return plaintext; } catch (exc) { throw exc instanceof jose_exception_1.JoseException ? exc : new invalid_jsonwebencryption_exception_1.InvalidJsonWebEncryptionException(null, exc); } } /** * Generates the Authentication Tag of the provided Ciphertext. * * @param ciphertext Ciphertext to be Decrypted. * @param iv Initialization Vector. * @param aad Additional Authenticated Data. * @param key Content Encryption Key. * @returns Authentication Tag. */ getAuthTag(ciphertext, iv, aad, key) { const len = aad.length << 3; const buf = Buffer.alloc(8); buf.writeUInt32BE(Math.floor(len / 2 ** 32), 0); buf.writeUInt32BE(len % 2 ** 32, 4); const data = Buffer.concat([aad, iv, ciphertext, buf]); return (0, crypto_1.createHmac)(this.hash, key) .update(data) .digest() .slice(0, this.keySize >> 3); } } /** * AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm. */ exports.A128CBC_HS256 = new CbcAlgorithm('A128CBC-HS256'); /** * AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm. */ exports.A192CBC_HS384 = new CbcAlgorithm('A192CBC-HS384'); /** * AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm. */ exports.A256CBC_HS512 = new CbcAlgorithm('A256CBC-HS512'); //# sourceMappingURL=cbc.algorithm.js.map