@tsmx/object-hmac
Advanced tools
Comparing version 1.1.0 to 1.1.1
const crypto = require('crypto'); | ||
const jt = require('@tsmx/json-traverse'); | ||
const defaultHmacAttribute = '__hmac'; | ||
const hmacHash = 'sha256'; | ||
const hmacEncoding = 'hex'; | ||
function createOrderedObjectString(obj) { | ||
@@ -16,3 +20,3 @@ let attributes = []; | ||
function createHmac(obj, key, hmacAttribute = '__hmac') { | ||
function createHmac(obj, key, hmacAttribute = defaultHmacAttribute) { | ||
const hmac = calculateHmac(obj, key); | ||
@@ -23,8 +27,8 @@ obj[hmacAttribute] = hmac; | ||
function calculateHmac(obj, key) { | ||
let hmac = crypto.createHmac('sha256', key); | ||
let hmac = crypto.createHmac(hmacHash, key); | ||
hmac.update(createOrderedObjectString(obj)); | ||
return hmac.digest('hex'); | ||
return hmac.digest(hmacEncoding); | ||
} | ||
function verifyHmac(obj, key, hmacAttribute = '__hmac') { | ||
function verifyHmac(obj, key, hmacAttribute = defaultHmacAttribute) { | ||
if (!obj) return false; | ||
@@ -31,0 +35,0 @@ const providedHmac = obj[hmacAttribute]; |
{ | ||
"name": "@tsmx/object-hmac", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "Create and verify HMAC's for JSON objects", | ||
@@ -22,6 +22,13 @@ "author": "tsmx <dev@tsmx.net>", | ||
"JSON", | ||
"object", | ||
"HMAC", | ||
"MAC", | ||
"message", | ||
"authentication", | ||
"hash", | ||
"key", | ||
"sign", | ||
"verify", | ||
"data-integrity" | ||
"data-integrity", | ||
"SHA-256" | ||
], | ||
@@ -28,0 +35,0 @@ "devDependencies": { |
@@ -11,6 +11,8 @@ # [**@tsmx/object-hmac**](https://github.com/tsmx/object-hmac) | ||
Easily 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. | ||
Easily 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. | ||
Users of a version prior to v1.1.0 please see the [important note](#note-for-users-of-older-versions). | ||
The generated HMAC is independent of the JSON's attribute order and therefore stable for content-identical objects. See [calculateHmac](#calculatehmacobj-key). | ||
Users of an older version prior to v1.1.0 please see the [important note](#note-for-users-of-older-versions-prior-to-v110). | ||
## Usage | ||
@@ -21,3 +23,3 @@ | ||
```js | ||
const objectHmac = require('@tsmx/object-hmac'); | ||
const oh = require('@tsmx/object-hmac'); | ||
const key = 'HmacSecret-0815'; | ||
@@ -31,5 +33,10 @@ | ||
objectHmac.createHmac(person, key); | ||
oh.createHmac(person, key); | ||
// person = {"name":"Max","age":32,"hobbies":["sports","travelling"],"__hmac":"37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f"} | ||
// person = { | ||
// name: 'Max', | ||
// age: 32, | ||
// hobbies: ['sports','travelling'], | ||
// __hmac:'37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f' | ||
// } | ||
``` | ||
@@ -40,8 +47,13 @@ | ||
```js | ||
// person = {"name":"Max","age":32,"hobbies":["sports","travelling"],"__hmac":"37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f"} | ||
// person = { | ||
// name: 'Max', | ||
// age: 32, | ||
// hobbies: ['sports','travelling'], | ||
// __hmac:'37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f' | ||
// } | ||
const objectHmac = require('@tsmx/object-hmac'); | ||
const oh = require('@tsmx/object-hmac'); | ||
const key = 'HmacSecret-0815'; | ||
let verification = objectHmac.verifyHmac(person, key); | ||
let verification = oh.verifyHmac(person, key); | ||
// true | ||
@@ -51,3 +63,3 @@ | ||
let verificationAfterChange = objectHmac.verifyHmac(person, key); | ||
let verificationAfterChange = oh.verifyHmac(person, key); | ||
// false | ||
@@ -59,3 +71,3 @@ ``` | ||
```js | ||
const objectHmac = require('@tsmx/object-hmac'); | ||
const oh = require('@tsmx/object-hmac'); | ||
const key = 'HmacSecret-0815'; | ||
@@ -69,3 +81,3 @@ | ||
let hmac = objectHmac.calculateHmac(person, key); | ||
let hmac = oh.calculateHmac(person, key); | ||
// 37c2e448b6f4a72c9d8abc9a1ab6cada602c3785148caeeed5498ed065ddc69f | ||
@@ -76,3 +88,3 @@ ``` | ||
### createHmac(obj, key, hmacAttribute = '__hmac') | ||
### createHmac(obj, key, hmacAttribute) | ||
@@ -100,3 +112,3 @@ Calculates the HMAC of `obj` and attaches it as value of attribute `obj[hmacAttribute]`. | ||
### verifyHmac(obj, key, hmacAttribute = '__hmac') | ||
### verifyHmac(obj, key, hmacAttribute) | ||
@@ -112,3 +124,3 @@ Verifies the HMAC attached to `obj`. Returns `true` if the validation was successful, otherwise false `false`. | ||
The verification would not fail, just because the JSON's attributes order has changed. For more details see [calculateHmac](#calculateHmacobj-key). | ||
The verification would not fail, just because the JSON's attributes order has changed. For more details see [calculateHmac](#calculatehmacobj-key). | ||
@@ -149,3 +161,3 @@ #### obj | ||
let hmac = objectHmac.calculateHmac(person, key); | ||
let hmac = oh.calculateHmac(person, key); | ||
@@ -158,7 +170,9 @@ let person2 = { | ||
let hmac2 = objectHmac.calculateHmac(person, key); | ||
let hmac2 = oh.calculateHmac(person2, key); | ||
/// hmac === hmac2 | ||
/// (hmac === hmac2) is true | ||
``` | ||
Please 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. | ||
#### obj | ||
@@ -184,5 +198,5 @@ | ||
To 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 used. | ||
To 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. | ||
### Note for users of older versions | ||
### Note for users of older versions prior to v1.1.0 | ||
@@ -189,0 +203,0 @@ Prior 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. |
@@ -98,2 +98,7 @@ describe('object-hmac test suite', () => { | ||
it('test a failed HMAC verification - changed array order', async (done) => { | ||
expect(objectHmac.verifyHmac(testObjects.testObjectWithHmacChangedArrayOrder, testKey)).toBeFalsy(); | ||
done(); | ||
}); | ||
it('test a failed HMAC verification - added object attribute', async (done) => { | ||
@@ -100,0 +105,0 @@ expect(objectHmac.verifyHmac(testObjects.testObjectAddedAttribute, testKey)).toBeFalsy(); |
@@ -36,2 +36,14 @@ module.exports.testObject = | ||
module.exports.testObjectWithHmacChangedArrayOrder = | ||
{ | ||
title: 'Test-Object', | ||
numbers: [123, 12, 1], | ||
subObject: { | ||
name: 'Max', | ||
age: 32, | ||
hobbies: ['sports', 'travelling'] | ||
}, | ||
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7' | ||
} | ||
module.exports.testObjectWithHmacChangedSubobjectOrder = | ||
@@ -38,0 +50,0 @@ { |
17998
257
199