{"id":19889529,"url":"https://github.com/tsmx/object-hmac","last_synced_at":"2025-08-24T10:13:44.971Z","repository":{"id":57168122,"uuid":"369635973","full_name":"tsmx/object-hmac","owner":"tsmx","description":"Create and verify HMAC's for JSON objects.","archived":false,"fork":false,"pushed_at":"2024-06-18T19:50:21.000Z","size":709,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-26T22:59:00.253Z","etag":null,"topics":["data-integrity","hash","hmac","json","json-objects","object","objects-hmac","sha-256","sign","verify"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tsmx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-21T19:32:23.000Z","updated_at":"2024-06-18T19:49:41.000Z","dependencies_parsed_at":"2023-01-30T02:01:04.725Z","dependency_job_id":"a7fe46e0-2753-4960-9347-fb33c2c8168a","html_url":"https://github.com/tsmx/object-hmac","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobject-hmac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobject-hmac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobject-hmac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsmx%2Fobject-hmac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsmx","download_url":"https://codeload.github.com/tsmx/object-hmac/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223893165,"owners_count":17220834,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-integrity","hash","hmac","json","json-objects","object","objects-hmac","sha-256","sign","verify"],"created_at":"2024-11-12T18:10:38.518Z","updated_at":"2024-11-12T18:10:38.972Z","avatar_url":"https://github.com/tsmx.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [**@tsmx/object-hmac**](https://github.com/tsmx/object-hmac)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n![npm (scoped)](https://img.shields.io/npm/v/@tsmx/object-hmac)\n![node-current (scoped)](https://img.shields.io/node/v/@tsmx/object-hmac)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/tsmx/object-hmac/git-build.yml?branch=master)](https://img.shields.io/github/actions/workflow/status/tsmx/object-hmac/git-build.yml?branch=master)\n[![Coverage Status](https://coveralls.io/repos/github/tsmx/object-hmac/badge.svg?branch=master)](https://coveralls.io/github/tsmx/object-hmac?branch=master)\n\n\u003e Create and verify HMAC's for JSON objects.\n\nEasily create and verify [keyed-hash message authentication codes (HMAC's)](https://en.wikipedia.org/wiki/HMAC) for your JSON objects to ensure data integrity and authenticity.\n\nThe generated HMAC is independent of the JSON's attribute order and therefore stable for content-identical objects. See [calculateHmac](#calculatehmacobj-key).\n\nUsers of an older version prior to v1.1.0 please see the [important note](#note-for-users-of-older-versions-prior-to-v110).\n\n## Usage\n\n### Create and add HMAC to a JSON object\n\n```js\nconst oh = require('@tsmx/object-hmac');\nconst key = 'HmacSecret-0815';\n\nlet person = {\n    name: 'Max',\n    age: 32,\n    hobbies: ['sports', 'travelling']\n};\n\noh.createHmac(person, key);\n\n// person = {\n//   name: 'Max',\n//   age: 32,\n//   hobbies: ['sports','travelling'],\n//   __hmac:'37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f'\n// }\n```\n\n### Verify HMAC for a JSON object\n\n```js\n// person = {\n//   name: 'Max',\n//   age: 32,\n//   hobbies: ['sports','travelling'],\n//   __hmac:'37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f'\n// }\n\nconst oh = require('@tsmx/object-hmac');\nconst key = 'HmacSecret-0815';\n\nlet verification = oh.verifyHmac(person, key);\n// true\n\nperson.age = 33;\n\nlet verificationAfterChange = oh.verifyHmac(person, key);\n// false\n```\n\n### Only calculate HMAC for a JSON object\n\n```js\nconst oh = require('@tsmx/object-hmac');\nconst key = 'HmacSecret-0815';\n\nlet person = {\n    name: 'Max',\n    age: 32,\n    hobbies: ['sports', 'travelling']\n};\n\nlet hmac = oh.calculateHmac(person, key);\n// 37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f\n```\n\n## API\n\n### createHmac(obj, key, hmacAttribute)\n\nCalculates the HMAC of `obj` and attaches it as value of attribute `obj[hmacAttribute]`.\n\n#### obj\n\nType: `Object`\n\nThe object to calculate and store the HMAC for.\n\n#### key\n\nType: `String`\n\nThe key to calculate the objects HMAC.\n\n#### hmacAttribute\n\nType: `String`\nDefault: `__hmac`\n\nThe name of the attribute to store the HMAC value in `obj`. Make sure that the name of the attribute is not overlapping with other attributes already in use.\n\n### verifyHmac(obj, key, hmacAttribute)\n\nVerifies the HMAC attached to `obj`. Returns `true` if the validation was successful, otherwise false `false`.\n\nThe verification would fail and return `false`, if...\n- `obj` is null\n- `obj` doesn't provide a HMAC to check against\n- `obj` was manipulated: at least one attribute was changed, added or deleted (deep-inspection including all nested objects/arrays)\n- the HMAC of `obj` was manipulated\n- `key` is deviating from the one the HMAC was created with\n\nThe verification would not fail, just because the JSON's attributes order has changed. For more details see [calculateHmac](#calculatehmacobj-key).\n\n#### obj\n\nType: `Object`\n\nThe object of which the HMAC should be verified. The given HMAC to be verified is assumed to exist as an attribute in the object itself: `obj[hmacAttribute]`.\n\n#### key\n\nType: `String`\n\nThe key to calculate the objects HMAC and validate against the given one. Must be identical to the `key` that was used to create the original HMAC for the object for a successful verification.\n\n#### hmacAttribute\n\nType: `String`\nDefault: `__hmac`\n\nThe name of the attribute for the HMAC value in `obj` to be verified against.\n\n### calculateHmac(obj, key)\n\nCalculates and returns the HMAC of `obj`.\n\nTakes **all** of `obj` attributes into account for calculating the HMAC. So make sure that there isn't already a HMAC attribute created in the object. Otherwise this would also being used as an input for the calculation.\n\nThe calculation of the HMAC is independent of the order of your JSON's attributes. This means that the HMAC of content-identical objects with just another order of attributes will always by the same.\n\n```js\nlet person = {\n    name: 'Max',\n    age: 32,\n    hobbies: ['sports', 'travelling']\n};\n\nlet hmac = oh.calculateHmac(person, key);\n\nlet person2 = {\n    age: 32,\n    hobbies: ['sports', 'travelling'],\n    name: 'Max'\n};\n\nlet hmac2 = oh.calculateHmac(person2, key);\n\n/// (hmac === hmac2) is true\n```\n\nPlease not that this order-independency does not apply to array elements. Arrays containing the same values in another order are not content-identical for obvious reasons. So the HMAC's of `{ hobbies: ['sports', 'travelling'] }` and `{ hobbies: ['travelling', 'sports'] }` are different.\n\n#### obj\n\nType: `Object`\n\nThe object to calculate the HMAC for.\n\n#### key\n\nType: `String`\n\nThe key to calculate the objects HMAC.\n\n## Under the hood\n\nTo create and verify the HMAC, standard [NodeJS crypto functions](https://nodejs.org/docs/latest-v12.x/api/crypto.html#crypto_class_hmac) are used.\n\nThe HMAC is generated by using the following parameters:\n- Hash function: SHA-256\n- Digest output encoding: Hexadecimal String\n\nTo provide a stable (attribute-order independent) representation of the JSON object, a sorted traversal using the library [@tsmx/json-traverse](https://www.npmjs.com/package/@tsmx/json-traverse) is applied.\n\n### Note for users of older versions prior to v1.1.0\n\nPrior to v1.1.0 the algorithm used to generate the JSON's representation for the HMAC generation didn't to 100% guarantee a deterministic behaviour which could in some cases result in a failing verification although it should succeed.\n\nTherefore it is **strongly recommended** to update to version 1.1.0 or higher. If you have any HMAC's persistently stored which where generated with a 1.0.x version you must re-calculate them with v1.1.0 or higher when upgrading.  \n\n## Test\n\n```\nnpm install\nnpm test\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmx%2Fobject-hmac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsmx%2Fobject-hmac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsmx%2Fobject-hmac/lists"}