hmac-obj
Version:
JavaScript implementation of HMAC generation and verification for the browser and node.js.
1 lines • 31.1 kB
Source Map (JSON)
{"version":3,"file":"hmac-obj.cjs","sources":["../src/helpers.js","../src/hmac-obj.js"],"sourcesContent":["class PermissionError extends Error {\n constructor(message) {\n super(message);\n this.name = \"PermissionError\";\n }\n}\n\nconst cryptoSubtle = {\n\n importKey: async (key, digestmod, format=\"raw\", permitExports=false) => {\n return await globalThis.crypto.subtle.importKey(\n format,\n key,\n {\n name: \"HMAC\",\n hash: {name: digestmod}\n },\n permitExports,\n [\"sign\", \"verify\"]\n );\n },\n\n generateKey: async (digestmod, permitExports=false) => {\n return await globalThis.crypto.subtle.generateKey(\n {\n name: \"HMAC\",\n hash: {name: digestmod}\n },\n permitExports,\n [\"sign\", \"verify\"]\n );\n },\n\n exportKey: async (key, format=\"raw\") => {\n if (!key.extractable) {\n throw new PermissionError(\"Key exports are not allowed. You can permit this during key-generation.\");\n }\n return await globalThis.crypto.subtle.exportKey(format, key);\n },\n\n sign: async (msg, key) => { \n return await globalThis.crypto.subtle.sign(\n {\n name: \"HMAC\",\n hash: key.algorithm.hash.name\n },\n key,\n msg\n );\n },\n\n verify: async (msg, signature, key) => { \n return await globalThis.crypto.subtle.verify(\n \"HMAC\",\n key,\n signature,\n msg\n );\n },\n};\n\nconst getDigestModFromParam = (digestmod, digestmods) => {\n \n if (!digestmod) {\n throw new TypeError(\"Missing required parameter 'digestmod'.\");\n }\n\n let bits = [].concat(String(digestmod).match(/[0-9]+/)).at(0)|0;\n digestmod = `SHA-${bits}`;\n\n if (!digestmods.includes(digestmod)) {\n throw new TypeError(`Available digestmod are: '${digestmods.join(\", \")}'.`);\n }\n\n if (bits === 1) {\n bits = 160;\n }\n\n return [ digestmod, bits ];\n};\n\n\nexport {\n cryptoSubtle,\n getDigestModFromParam,\n PermissionError\n};\n","/**\n * [HMACObj]{@link https://github.com/UmamiAppearance/HMACObj}\n *\n * @version 1.0.6\n * @author UmamiAppearance [mail@umamiappearance.eu]\n * @license MIT\n */\n\nimport { cryptoSubtle, getDigestModFromParam, PermissionError } from \"./helpers.js\";\nimport { BaseEx } from \"base-ex\";\n\nlet BASE_EX;\nif (typeof BaseEx === \"undefined\") {\n throw new Error(\"BaseEx is required for this module to work. Please make sure the whole library or the BaseEx class can be globally found under the name 'BaseEx'.\");\n}\n\nif (\"BaseEx\" in BaseEx) {\n BASE_EX = new BaseEx.BaseEx();\n} else {\n BASE_EX = new BaseEx();\n}\n\nconst DIGESTMODS = [\"SHA-1\", \"SHA-256\", \"SHA-384\", \"SHA-512\"];\nconst KEY_FORMATS = [\"raw\", \"jwk\"];\n\n\n/**\n * Creates a HMAC-SHA-(1-512) object for JavaScript.\n * It is related to pythons hmac library in its methods\n * and features but with many extras.\n * \n * It provides an easy access to the global Crypto.subtle\n * method, and also makes it possible to get multiple\n * different digest methods.\n * \n * @see: https://docs.python.org/3/library/hmac.html\n */\nexport default class HMACObj {\n\n #bits = null;\n #digest = null;\n #digestmod = null;\n #input = [];\n #key = null;\n #keyFormats = this.constructor.keyFormats();\n #keyIsExportable = null;\n\n\n /**\n * Creates a HMAC Object.\n * @param {string|number} digestmod - The parameter must contain one of the numbers (1/256/384/512), eg: SHA-1, sha256, 384, ... \n */\n constructor(digestmod) {\n [ this.#digestmod, this.#bits ] = getDigestModFromParam(digestmod, DIGESTMODS);\n this.#addConverters();\n }\n\n\n /**\n * BaseEx instance.\n */\n static baseEx = BASE_EX;\n\n\n /**\n * Static method to receive information about the \n * available digestmod.\n * @returns {set} - A set of available digestmod.\n */\n static digestmodsAvailable() {\n return new Set(DIGESTMODS);\n }\n\n\n /**\n * Static method to receive information about the\n * available key formats.\n * @returns {set} - A set of available key formats.\n */\n static keyFormats() {\n return new Set(KEY_FORMATS);\n }\n\n\n /**\n * Static method to generate a crypto key for the HMAC algorithm.\n * @param {string|number} digestmod - The parameter must contain one of the numbers (1/256/384/512), eg: SHA-1, sha256, 384, ...\n * @param {boolean} [permitExports=false] - If true the key can get exported. \n * @returns {Object} - Crypto Key.\n */\n static async generateKey(digestmod=\"\", permitExports=false) {\n digestmod = getDigestModFromParam(digestmod, DIGESTMODS).at(0);\n return await cryptoSubtle.generateKey(digestmod, permitExports);\n }\n\n\n /**\n * Return a === b. This function uses an approach designed\n * to prevent timing analysis by avoiding content-based\n * short circuiting behavior, making it appropriate for\n * cryptography.\n * a and b (or more precisely their byte representation)\n * must both be of the same type.\n * @param {*} a \n * @param {*} b \n * @returns \n */\n static compareDigest(a, b) {\n\n if (typeof a === \"undefined\" || typeof b === \"undefined\") {\n throw new Error(\"HMACobj.compareDigest takes exactly two positional arguments.\");\n }\n\n a = BASE_EX.byteConverter.encode(a, \"uint8\");\n b = BASE_EX.byteConverter.encode(b, \"uint8\");\n\n // set the greater array as 'A'\n let A, B; \n if (a.byteLength > b.byteLength) {\n A = a;\n B = b;\n } else {\n A = b;\n B = a;\n }\n\n // Walk through the greater (or equally sized) array and\n // compare each value with the value at the corresponding\n // index. (If B is smaller it will return undefined at a\n // certain point).\n const test = A.map((byte, i) => {\n return byte === B.at(i);\n });\n\n // Only if every value is true the result of the \n // reduced array will be 1. If one value is false\n // the result will be zero.\n const passed = Boolean(test.reduce((x, y) => x*y));\n \n return passed;\n }\n\n\n /**\n * Asynchronously creates a new instance. In contrast\n * to the regular new operator a message and key can \n * be provided. If a message is set, a key must also be\n * handed over or a crypto key gets generated automatically.\n * A message gets passed to the 'update' method.\n * \n * @param {*} key - Almost any input can be provided. It gets converted to bytes and used for the crypto key generation.\n * @param {*} msg - Input gets converted to bytes and processed by crypto.subtle.digest.\n * @param {string|number} digestmod - The parameter must contain one of the numbers (1/256/384/512), eg: SHA-1, sha256, 384, ... \n * @param {string} [keyFormat=\"raw\"] - As defined by KEY_FORMATS. If not set to raw, 'key' must match the format.\n * @param {boolean} [permitExports=false] - If a key is getting generated, this bool sets it to exportable or not.\n * @returns {Object} - A HMACObj instance.\n */\n static async new(key=null, msg=null, digestmod=\"\", keyFormat=\"raw\", permitExports=false) {\n \n const hmacObj = new this(digestmod);\n\n if (key) {\n if (keyFormat === \"object\") {\n await hmacObj.setKey(key);\n } else {\n await hmacObj.importKey(key, keyFormat, permitExports);\n }\n }\n\n if (msg !== null) {\n if (!key) {\n await hmacObj.generateKey();\n console.warn(\"A message but no key was provided. The key was generated for you.\");\n }\n await hmacObj.update(msg);\n }\n return hmacObj;\n }\n\n\n /**\n * The size of the resulting hash in bytes.\n */\n get digestSize() {\n return this.#bits / 8;\n }\n\n\n /**\n * The internal block size of the hash algorithm in bytes.\n */\n get blockSize() {\n return this.#bits > 256 ? 128 : 64;\n }\n\n\n /**\n * The canonical name of this HMAC, always uppercase,\n * e.g. HMAC-SHA-256.\n */\n get name() {\n return \"HMAC-\" + this.#digestmod;\n }\n\n\n /**\n * Shortcut to the BaseEx byte converter.\n * @param {*} input - Almost any input.\n * @returns {Object} - Uint8Array/Byte representation of the input.\n */\n #ensureBytes(input) {\n return BASE_EX.byteConverter.encode(input, \"bytes\");\n } \n\n\n /**\n * Test wether the provided format matches the\n * predetermined formats.\n */\n #testFormat(format) {\n if (!this.#keyFormats.has(format)) { \n throw new TypeError(\n `Invalid key format '${format}'\\n\\nValid formats are: ${KEY_FORMATS.join(\", \")}`\n );\n }\n }\n\n\n /**\n * Test wether a key is assigned to the current instance.\n */\n #testKeyAvail() {\n if (this.#key === null) {\n throw new Error(\"No key is assigned yet. Import or generate key.\");\n }\n }\n\n\n /**\n * Convert buffer to many different representations.\n * (Helper for method 'sign')\n * @param {ArrayBuffer} buffer - ArrayBuffer.\n * @param {string} base - Base Representation as required by BaseEx.\n * @returns {string} - Base Representation.\n */\n #bufferToBase(buffer, base) {\n const decapitalize = str => str.charAt(0).toLowerCase().concat(str.slice(1));\n const errMsg = \"Invalid base conversion keyword.\";\n base = decapitalize(base.replace(/^to/, \"\"));\n \n if (base === \"hex\" || base == \"hexdigest\") {\n base = \"base16\";\n }\n\n else if (base === \"bytes\") {\n base = \"byteConverter\";\n }\n\n else if ((/SimpleBase/i).test(base)) {\n base = `base${[].concat(String(base).match(/[0-9]+/)).at(0)|0}`;\n if (!(base in BASE_EX.simpleBase)) {\n throw new TypeError(errMsg);\n }\n return BASE_EX.simpleBase[base].encode(buffer); \n }\n \n if (!(base in BASE_EX)) {\n throw new TypeError(errMsg);\n }\n\n return BASE_EX[base].encode(buffer);\n }\n\n\n /**\n * Update the HMAC object with almost any input. The input\n * gets converted to a Uint8Array. Unless 'replace' is set\n * to true, repeated calls are equivalent to a single call\n * with the concatenation of all the arguments:\n * hmacObj.update(a); hmacObj.update(b) is in many occasions\n * equivalent to hmacObj.update(a+b).\n * \n * (Note: The process is a concatenation of bytes. Take as\n * an exception for instance:\n * hmacObj.update(1); hmacObj.update(2) which is not the same\n * as hmacObj.update(1+2))\n * \n * @param {*} msg - Input gets converted to bytes and processed by crypto.subtle.digest. \n * @param {boolean} replace - If true, the input is not concatenated with former input.\n */\n async update(msg, replace=false) {\n msg = this.#ensureBytes(msg);\n \n this.#testKeyAvail();\n \n if (replace) {\n this.#input = Array.from(msg);\n } else {\n this.#input = this.#input.concat(Array.from(msg));\n }\n \n this.#digest = await cryptoSubtle.sign(\n Uint8Array.from(this.#input),\n this.#key\n );\n }\n\n\n /**\n * Shortcut to 'update(input, true)'.\n * @param {*} msg - Input gets converted to bytes and processed by crypto.subtle.digest. \n */\n async replace(msg) {\n await this.update(msg, true);\n }\n\n\n /**\n * Method to replace the assigned Crypto Key.\n * @param {Object} cryptoKey - The new Crypto Key. \n */\n async setKey(cryptoKey) {\n this.#key = cryptoKey;\n\n if (this.#input.length) {\n console.warn(\"A new crypto key was established. A fresh digest is now getting calculated.\");\n this.#digest = await cryptoSubtle.sign(\n Uint8Array.from(this.#input),\n this.#key\n );\n }\n }\n\n\n /**\n * Import a Crypto Key from almost any input or\n * a pre existing key.\n * @param {*} key - Almost any input can be provided. It gets converted to bytes and used for the crypto key generation.\n * @param {string} [format=\"raw\"] - As defined by KEY_FORMATS. If not set to raw, 'key' must match the format.\n * @param {boolean} [permitExports=false] - This bool sets the generated key to exportable or not.\n */\n async importKey(key, format=\"raw\", permitExports=false) {\n \n if (format === \"raw\") {\n key = this.#ensureBytes(key);\n } else {\n this.#testFormat(format);\n }\n this.#keyIsExportable = permitExports;\n \n const keyObj = await cryptoSubtle.importKey(key, this.#digestmod, format, permitExports);\n await this.setKey(keyObj);\n\n }\n\n\n /**\n * Method to apply a auto generated Crypto Key\n * to the instance.\n * @param {boolean} [permitExports=true] - This bool sets the generated key to exportable or not.\n */\n async generateKey(permitExports=true) {\n this.#keyIsExportable = Boolean(permitExports);\n const keyObj = await cryptoSubtle.generateKey(this.#digestmod, this.#keyIsExportable);\n await this.setKey(keyObj);\n }\n\n\n /**\n * Exports the Crypto Key assigned to the instance,\n * if it is a exportable key.\n * @param {string} [format=\"raw\"] - As defined by KEY_FORMATS.\n * @returns {Object} - Crypto Key\n */\n async exportKey(format=\"raw\") {\n \n this.#testFormat(format);\n \n if (this.#key === null) {\n throw new Error(\"Key is unset.\");\n }\n \n if (!this.#keyIsExportable) {\n throw new PermissionError(\"Key exports are not allowed. You have to permit this before key-generation.\");\n }\n \n const key = await cryptoSubtle.exportKey(this.#key, format);\n return key;\n }\n\n\n /**\n * Return a copy (“clone”) of the hmac object. This can be used\n * to efficiently compute the digests of strings that share a\n * common initial substring.\n * @returns {Object} - HMACObject instance.\n */\n async copy() {\n return await this.constructor.new(\n this.#key,\n this.#input.length ? Uint8Array.from(this.#input) : null,\n this.#digestmod,\n \"object\",\n this.#keyIsExportable\n );\n }\n\n\n /**\n * Signs a single message independent from the current\n * instance message.\n * @param {*} msg - Input gets converted to bytes and processed by crypto.subtle.digest.\n * @param {*} [base=null] - Optional Base Representation as required by BaseEx.\n * @returns {ArrayBuffer|string} - ArrayBuffer or a representation of the signed message.\n */\n async sign(msg, base=null) {\n this.#testKeyAvail();\n \n msg = this.#ensureBytes(msg);\n const buffer = await cryptoSubtle.sign(msg, this.#key);\n \n if (base !== null) {\n return this.#bufferToBase(buffer, base);\n }\n \n return buffer;\n }\n\n\n /**\n * A given message and signature can be tested \n * if it is signed with the current instance\n * crypto key.\n * @param {*} msg - Message.\n * @param {ArrayBuffer} signature - Signature as ArrayBuffer. \n * @returns {boolean} - Verification result.\n */\n async verify(msg, signature) { \n msg = this.#ensureBytes(msg);\n this.#testKeyAvail();\n\n if (this.signature === null) {\n throw new TypeError(\"Signature must be provided\");\n }\n const isValid = await cryptoSubtle.verify(msg, signature, this.#key);\n return isValid;\n }\n\n\n /**\n * Returns the current digest as an ArrayBuffer;\n * @returns {ArrayBuffer}\n */\n digest() {\n return this.#digest;\n }\n\n \n /**\n * Appends BaseEx encoders to the returned object for the ability\n * to covert the byte array of a hash to many representations.\n */\n #addConverters() {\n \n const detach = (arr, str) => arr.splice(arr.indexOf(str), 1);\n const capitalize = str => str.charAt(0).toUpperCase().concat(str.slice(1));\n\n this.hexdigest = () => this.#digest\n ? BASE_EX.base16.encode(this.#digest)\n : null;\n \n const converters = Object.keys(BASE_EX);\n this.basedigest = {\n toSimpleBase: {}\n };\n\n detach(converters, \"base1\");\n detach(converters, \"byteConverter\");\n detach(converters, \"simpleBase\");\n\n for (const converter of converters) {\n this.basedigest[`to${capitalize(converter)}`] = (...args) => this.#digest \n ? BASE_EX[converter].encode(this.#digest, ...args)\n : null;\n }\n\n for (const converter in BASE_EX.simpleBase) {\n this.basedigest.toSimpleBase[capitalize(converter)] = (...args) => this.#digest\n ? BASE_EX.simpleBase[converter].encode(this.#digest, ...args)\n : null;\n }\n\n this.basedigest.toBytes = (...args) => this.#digest\n ? BASE_EX.byteConverter.encode(this.#digest, ...args)\n : null;\n }\n}\n"],"names":["BaseEx"],"mappings":"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"}