@jc-lab/jose
Version:
JSON Web Almost Everything - JWA, JWS, JWE, JWK, JWT, JWKS for Node.js with minimal dependencies
57 lines (44 loc) • 1.82 kB
JavaScript
const { strict: assert } = require('assert')
const { createCipheriv, createDecipheriv } = require('crypto')
const { KEYOBJECT } = require('../help/consts')
const { JWEInvalid, JWEDecryptionFailed } = require('../errors')
const checkInput = function (size, iv, tag) {
if (iv.length !== 12) {
throw new JWEInvalid('invalid iv')
}
if (arguments.length === 3) {
if (tag.length !== 16) {
throw new JWEInvalid('invalid tag')
}
}
}
const encrypt = (size, { [KEYOBJECT]: keyObject }, cleartext, { iv, aad = Buffer.alloc(0) }) => {
const key = keyObject.asInput ? keyObject.asInput() : keyObject
checkInput(size, iv)
const cipher = createCipheriv(`aes-${size}-gcm`, key, iv)
cipher.setAAD(aad)
const ciphertext = Buffer.concat([cipher.update(cleartext), cipher.final()])
const tag = cipher.getAuthTag()
return { ciphertext, tag }
}
const decrypt = (size, { [KEYOBJECT]: keyObject }, ciphertext, { iv, tag = Buffer.alloc(0), aad = Buffer.alloc(0) }) => {
const key = keyObject.asInput ? keyObject.asInput() : keyObject
checkInput(size, iv, tag)
try {
const cipher = createDecipheriv(`aes-${size}-gcm`, key, iv)
cipher.setAuthTag(tag)
cipher.setAAD(aad)
return Buffer.concat([cipher.update(ciphertext), cipher.final()])
} catch (err) {
throw new JWEDecryptionFailed()
}
}
module.exports = (JWA) => {
['A128GCM', 'A192GCM', 'A256GCM'].forEach((jwaAlg) => {
const size = parseInt(jwaAlg.substr(1, 3), 10)
assert(!JWA.encrypt.has(jwaAlg), `encrypt alg ${jwaAlg} already registered`)
assert(!JWA.decrypt.has(jwaAlg), `decrypt alg ${jwaAlg} already registered`)
JWA.encrypt.set(jwaAlg, encrypt.bind(undefined, size))
JWA.decrypt.set(jwaAlg, decrypt.bind(undefined, size))
})
}