New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@tsmx/object-hmac

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tsmx/object-hmac - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

test/testobject.json

15

object-hmac.js
const crypto = require('crypto');
const jt = require('@tsmx/json-traverse');
function createOrderedObjectString(obj) {
let attributes = [];
const callbacks = {
processValue: (key, value, _level, path, _isObjectRoot, _isArrayElement, _cbSetValue) => {
attributes.push((path.length > 0 ? (path.join('.') + '.') : '') + key + '=' + value);
}
};
jt.traverse(obj, callbacks);
attributes.sort();
return attributes.join('|');
}
function createHmac(obj, key, hmacAttribute = '__hmac') {

@@ -10,3 +23,3 @@ const hmac = calculateHmac(obj, key);

let hmac = crypto.createHmac('sha256', key);
hmac.update(JSON.stringify(obj));
hmac.update(createOrderedObjectString(obj));
return hmac.digest('hex');

@@ -13,0 +26,0 @@ }

7

package.json
{
"name": "@tsmx/object-hmac",
"version": "1.0.1",
"version": "1.1.0",
"description": "Create and verify HMAC's for JSON objects",

@@ -17,3 +17,3 @@ "author": "tsmx <dev@tsmx.net>",

"type": "git",
"url": "git+https://github.com/tsmx/object-hmac.git"
"url": "https://github.com/tsmx/object-hmac.git"
},

@@ -30,3 +30,6 @@ "license": "MIT",

"jest": "^26.6.3"
},
"dependencies": {
"@tsmx/json-traverse": "^1.0.3"
}
}

@@ -11,4 +11,6 @@ # [**@tsmx/object-hmac**](https://github.com/tsmx/object-hmac)

Easily create and verify [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).
## Usage

@@ -102,2 +104,4 @@

The verification would not fail, just because the JSON's attributes order has changed. For more details see [calculateHmac](#calculateHmacobj-key).
#### obj

@@ -128,2 +132,24 @@

The 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.
```js
let person = {
name: 'Max',
age: 32,
hobbies: ['sports', 'travelling']
};
let hmac = objectHmac.calculateHmac(person, key);
let person2 = {
age: 32,
hobbies: ['sports', 'travelling'],
name: 'Max'
};
let hmac2 = objectHmac.calculateHmac(person, key);
/// hmac === hmac2
```
#### obj

@@ -149,3 +175,10 @@

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.
### Note for users of older versions
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.
Therefore 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.
## Test

@@ -152,0 +185,0 @@

@@ -6,3 +6,3 @@ describe('object-hmac test suite', () => {

const testKeyBroken = 'HmacSecret-4711';
const testHmac = 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638ac3b';
const testHmac = 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7';
const testHmacAttribute = '__hmac';

@@ -17,2 +17,13 @@ const testHmacAttributeDifferent = '_signature';

it('tests a successful HMAC creation and verification - end-to-end', async (done) => {
let person = {
name: 'Max',
age: 32
}
objectHmac.createHmac(person, testKey);
expect(person[testHmacAttribute]).toBeDefined();
expect(objectHmac.verifyHmac(person, testKey)).toBeTruthy();
done();
});
it('tests a successful HMAC calculation', async (done) => {

@@ -45,2 +56,26 @@ const hmac = objectHmac.calculateHmac(testObjects.testObject, testKey);

it('test a successful HMAC verification - JSON with changed attribute order', async (done) => {
expect(objectHmac.verifyHmac(testObjects.testObjectWithHmacChangedOrder, testKey)).toBeTruthy();
done();
});
it('test a successful HMAC verification - JSON with changed attribute order in a subobject', async (done) => {
expect(objectHmac.verifyHmac(testObjects.testObjectWithHmacChangedSubobjectOrder, testKey)).toBeTruthy();
done();
});
it('test a successful HMAC verification - JSON loaded from a file via require', async (done) => {
let testObj = require('./testobject');
expect(objectHmac.verifyHmac(testObj, testKey)).toBeTruthy();
done();
});
it('test a successful HMAC verification - JSON loaded from a file via fs', async (done) => {
let fs = require('fs');
let path = require('path');
let testObj = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'testobject.json'), 'utf8'));
expect(objectHmac.verifyHmac(testObj, testKey)).toBeTruthy();
done();
});
it('test a successful HMAC verification with a different attribute name', async (done) => {

@@ -47,0 +82,0 @@ expect(objectHmac.verifyHmac(testObjects.testObjectWithHmacDifferentAttribute, testKey, testHmacAttributeDifferent)).toBeTruthy();

@@ -21,5 +21,29 @@ module.exports.testObject =

},
__hmac: 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638ac3b'
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}
module.exports.testObjectWithHmacChangedOrder =
{
title: 'Test-Object',
subObject: {
name: 'Max',
age: 32,
hobbies: ['sports', 'travelling']
},
numbers: [1, 12, 123],
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}
module.exports.testObjectWithHmacChangedSubobjectOrder =
{
title: 'Test-Object',
numbers: [1, 12, 123],
subObject: {
name: 'Max',
hobbies: ['sports', 'travelling'],
age: 32
},
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}
module.exports.testObjectWithHmacDifferentAttribute =

@@ -34,3 +58,3 @@ {

},
_signature: 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638ac3b'
_signature: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}

@@ -47,3 +71,3 @@

},
__hmac: 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638ac3b'
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}

@@ -61,3 +85,3 @@

},
__hmac: 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638ac3b'
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}

@@ -73,3 +97,3 @@

},
__hmac: 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638ac3b'
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb15215c7'
}

@@ -79,3 +103,3 @@

{
title: 'Test-ObjectX',
title: 'Test-Object',
numbers: [1, 12, 123],

@@ -87,3 +111,3 @@ subObject: {

},
__hmac: 'bb83e36f2c030af71803fd6a82b49ea638944bb6638351754a967f4f5638aczz'
__hmac: 'd5d182ef5b153107defbe4f96583c03ec3bd154ba38ca7ac41d0975eb1521xxx'
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc