@guarani/jose
Version:
Implementation of the RFCs of the JOSE Working Group.
106 lines (105 loc) • 5.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonWebEncryption = void 0;
const invalid_json_web_encryption_exception_1 = require("../exceptions/invalid-json-web-encryption.exception");
const jose_exception_1 = require("../exceptions/jose.exception");
const jsonwebencryption_keywrap_algorithms_registry_1 = require("./algorithms/alg/jsonwebencryption-keywrap-algorithms-registry");
const jsonwebencryption_contentencryption_algorithms_registry_1 = require("./algorithms/enc/jsonwebencryption-contentencryption-algorithms-registry");
const jsonwebencryption_compression_algorithms_registry_1 = require("./algorithms/zip/jsonwebencryption-compression-algorithms-registry");
const jsonwebencryption_header_1 = require("./jsonwebencryption.header");
/**
* Implementation of {@link https://www.rfc-editor.org/rfc/rfc7516.html RFC 7516}.
*/
class JsonWebEncryption {
/**
* Instantiates a new JSON Web Encryption based on the provided JSON Web Encryption Header and Plaintext.
*
* @param header JSON Web Encryption Header.
* @param plaintext Buffer to be used as the Plaintext.
*/
constructor(header, plaintext) {
if (plaintext !== undefined && !Buffer.isBuffer(plaintext)) {
throw new TypeError('Invalid JSON Web Encryption Plaintext.');
}
this.header = new jsonwebencryption_header_1.JsonWebEncryptionHeader(header);
this.plaintext = Buffer.isBuffer(plaintext) ? plaintext : Buffer.alloc(0);
}
/**
* Decodes the provided JSON Web Encryption Token and returns its parsed Parameters.
*
* @param token JSON Web Encryption Token to be Decoded.
* @returns Parsed Parameters of the JSON Web Encryption Token.
*/
static decodeCompact(token) {
const splitToken = token.split('.');
if (splitToken.length !== 5) {
throw new invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException();
}
const [b64Header, b64Ek, b64Iv, b64Ciphertext, b64Tag] = splitToken;
const header = new jsonwebencryption_header_1.JsonWebEncryptionHeader(JSON.parse(Buffer.from(b64Header, 'base64url').toString('utf8')));
const ek = Buffer.from(b64Ek, 'base64url');
const iv = Buffer.from(b64Iv, 'base64url');
const ciphertext = Buffer.from(b64Ciphertext, 'base64url');
const tag = Buffer.from(b64Tag, 'base64url');
const aad = Buffer.from(b64Header, 'ascii');
return { aad, ciphertext, ek, header, iv, tag };
}
/**
* Deserializes a JSON Web Encryption Compact Token.
*
* @param token JSON Web Encryption Compact Token to be Deserialized.
* @param key JSON Web Key used to Deserialize the JSON Web Encryption Compact Token.
* @returns JSON Web Encryption containing the Deserialized JSON Web Encryption Header and Plaintext.
*/
static async deserializeCompact(token, key) {
try {
const { aad, ciphertext, ek, header, iv, tag } = this.decodeCompact(token);
const alg = jsonwebencryption_keywrap_algorithms_registry_1.JSON_WEB_ENCRYPTION_KEY_WRAP_ALGORITHMS_REGISTRY[header.alg];
const enc = jsonwebencryption_contentencryption_algorithms_registry_1.JSON_WEB_ENCRYPTION_CONTENT_ENCRYPTION_ALGORITHMS_REGISTRY[header.enc];
const zip = header.zip !== undefined ? jsonwebencryption_compression_algorithms_registry_1.JSON_WEB_ENCRYPTION_COMPRESSION_ALGORITHMS_REGISTRY[header.zip] : null;
const cek = await alg.unwrap(enc, key, ek, header);
let plaintext = await enc.decrypt(ciphertext, aad, iv, tag, cek);
if (zip !== null) {
plaintext = await zip.decompress(plaintext);
}
return new JsonWebEncryption(header, plaintext);
}
catch (exc) {
if (exc instanceof invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException) {
throw exc;
}
throw exc instanceof jose_exception_1.JoseException
? new invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException(exc)
: new invalid_json_web_encryption_exception_1.InvalidJsonWebEncryptionException(null, exc);
}
}
/**
* Serializes the JSON Web Encryption into a Compact Token.
*
* @param key JSON Web Key used to Serialize the JSON Web Encryption.
* @returns JSON Web Encryption Compact Token.
*/
async serializeCompact(key) {
let { header, plaintext } = this;
const alg = jsonwebencryption_keywrap_algorithms_registry_1.JSON_WEB_ENCRYPTION_KEY_WRAP_ALGORITHMS_REGISTRY[header.alg];
const enc = jsonwebencryption_contentencryption_algorithms_registry_1.JSON_WEB_ENCRYPTION_CONTENT_ENCRYPTION_ALGORITHMS_REGISTRY[header.enc];
const zip = header.zip !== undefined ? jsonwebencryption_compression_algorithms_registry_1.JSON_WEB_ENCRYPTION_COMPRESSION_ALGORITHMS_REGISTRY[header.zip] : null;
const iv = await enc.generateInitializationVector();
const { cek, ek, additionalHeaderParams } = await alg.wrap(enc, key);
if (additionalHeaderParams !== undefined) {
Object.assign(header, additionalHeaderParams);
}
const b64Header = Buffer.from(JSON.stringify(header), 'utf8').toString('base64url');
const aad = Buffer.from(b64Header, 'ascii');
if (zip !== null) {
plaintext = await zip.compress(plaintext);
}
const { ciphertext, tag } = await enc.encrypt(plaintext, aad, iv, cek);
const b64Ek = ek.toString('base64url');
const b64Iv = iv.toString('base64url');
const b64Ciphertext = ciphertext.toString('base64url');
const b64Tag = tag.toString('base64url');
return `${b64Header}.${b64Ek}.${b64Iv}.${b64Ciphertext}.${b64Tag}`;
}
}
exports.JsonWebEncryption = JsonWebEncryption;