use base58 encoding for signatures
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
142e9ec458
commit
612686a224
48
index.js
48
index.js
@ -103,10 +103,36 @@ function sign_object (obj, key, key_info = null) {
|
||||
obj,
|
||||
...(typeof key_info === 'object' ? key_info : { key_info })
|
||||
};
|
||||
const str = encoding.to_b64 (JSON.stringify (payload));
|
||||
const token = encoding.to_b64 (hash_sha512 (str, key), 'hex');
|
||||
const res = `${str}.${token}`;
|
||||
return encodeURIComponent (res);
|
||||
const str = encoding.to_b58 (JSON.stringify (payload));
|
||||
const token = encoding.to_b58 (hash_sha512 (str, key), 'hex');
|
||||
const res = `${str}.${token}.2`;
|
||||
return res;
|
||||
}
|
||||
|
||||
function parse_signature (str, key = null) {
|
||||
let dec = str.split ('.');
|
||||
const version = dec[2];
|
||||
const res = {};
|
||||
switch (version) {
|
||||
case '2':
|
||||
res.json = JSON.parse (encoding.to_utf8 (dec[0], 'base58'));
|
||||
res.token = encoding.to_hex (dec[1], 'base58');
|
||||
break;
|
||||
default:
|
||||
dec = decodeURIComponent (str)
|
||||
.split ('.');
|
||||
res.json = JSON.parse (
|
||||
encoding.to_utf8 (dec[0], 'base64')
|
||||
);
|
||||
res.token = encoding.to_hex (dec[1], 'base64');
|
||||
break;
|
||||
}
|
||||
|
||||
if (key !== null) {
|
||||
const string_key = typeof key === 'string' ? key : key (res.json);
|
||||
res.hash = hash_sha512 (dec[0], string_key);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,13 +146,8 @@ function sign_object (obj, key, key_info = null) {
|
||||
function verify_signature_get_info (str, key, timeout = 0) {
|
||||
if (typeof str !== 'string')
|
||||
return null;
|
||||
const dec = decodeURIComponent (str)
|
||||
.split ('.');
|
||||
const json = JSON.parse (encoding.to_utf8 (dec[0], 'base64'));
|
||||
const token = encoding.to_hex (dec[1], 'base64');
|
||||
const string_key = typeof key === 'string' ? key : key (json);
|
||||
const verify_token = hash_sha512 (dec[0], string_key);
|
||||
if (token !== verify_token)
|
||||
const { json, token, hash } = parse_signature (str, key);
|
||||
if (token !== hash)
|
||||
return null;
|
||||
const time = Date.now () - json.iat;
|
||||
const num_timeout = typeof timeout === 'number' ? timeout : timeout (json);
|
||||
@ -159,9 +180,7 @@ function verify_signature (str, key, timeout = 0) {
|
||||
function get_signature_info (str) {
|
||||
if (typeof str !== 'string')
|
||||
return null;
|
||||
const dec = decodeURIComponent (str)
|
||||
.split ('.');
|
||||
const json = JSON.parse (encoding.to_utf8 (dec[0], 'base64'));
|
||||
const { json } = parse_signature (str);
|
||||
return json;
|
||||
}
|
||||
|
||||
@ -279,4 +298,3 @@ module.exports = {
|
||||
verify_signature,
|
||||
verify_signature_get_info
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sapphirecode/crypto-helper",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"main": "index.js",
|
||||
"author": {
|
||||
"name": "Timo Hocker",
|
||||
@ -34,7 +34,7 @@
|
||||
"compile": "tsc --allowJs --declaration --emitDeclarationOnly index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sapphirecode/encoding-helper": "^1.0.38"
|
||||
"@sapphirecode/encoding-helper": "^1.1.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
|
@ -10,8 +10,21 @@
|
||||
|
||||
const crypto = require ('../../index');
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
// eslint-disable-next-line max-lines-per-function, max-statements
|
||||
describe ('crypto helper', () => {
|
||||
beforeEach (() => {
|
||||
jasmine.clock ()
|
||||
.install ();
|
||||
const base_time = (new Date);
|
||||
jasmine.clock ()
|
||||
.mockDate (base_time);
|
||||
});
|
||||
|
||||
afterEach (() => {
|
||||
jasmine.clock ()
|
||||
.uninstall ();
|
||||
});
|
||||
|
||||
it ('random_hex', () => {
|
||||
const hex = crypto.random_hex (16);
|
||||
expect (hex.length)
|
||||
@ -200,12 +213,6 @@ describe ('crypto helper', () => {
|
||||
});
|
||||
|
||||
it ('should not fail verification if timeout unspecified', () => {
|
||||
jasmine.clock ()
|
||||
.install ();
|
||||
const base_time = (new Date);
|
||||
jasmine.clock ()
|
||||
.mockDate (base_time);
|
||||
|
||||
const obj = { foo: 'bar' };
|
||||
const str = crypto.sign_object (obj, 'baz');
|
||||
|
||||
@ -215,18 +222,9 @@ describe ('crypto helper', () => {
|
||||
const dec = crypto.verify_signature (str, 'baz');
|
||||
expect (obj)
|
||||
.toEqual (dec);
|
||||
|
||||
jasmine.clock ()
|
||||
.uninstall ();
|
||||
});
|
||||
|
||||
it ('should reject old signatures', () => {
|
||||
jasmine.clock ()
|
||||
.install ();
|
||||
const base_time = (new Date);
|
||||
jasmine.clock ()
|
||||
.mockDate (base_time);
|
||||
|
||||
const obj = { foo: 'bar' };
|
||||
const str = crypto.sign_object (obj, 'baz');
|
||||
|
||||
@ -236,18 +234,9 @@ describe ('crypto helper', () => {
|
||||
const dec = crypto.verify_signature (str, 'baz', 1);
|
||||
expect (dec)
|
||||
.toEqual (null);
|
||||
|
||||
jasmine.clock ()
|
||||
.uninstall ();
|
||||
});
|
||||
|
||||
it ('should not reject valid signatures', () => {
|
||||
jasmine.clock ()
|
||||
.install ();
|
||||
const base_time = (new Date);
|
||||
jasmine.clock ()
|
||||
.mockDate (base_time);
|
||||
|
||||
const obj = { foo: 'bar' };
|
||||
const str = crypto.sign_object (obj, 'baz');
|
||||
|
||||
@ -257,18 +246,9 @@ describe ('crypto helper', () => {
|
||||
const dec = crypto.verify_signature (str, 'baz', 100);
|
||||
expect (obj)
|
||||
.toEqual (dec);
|
||||
|
||||
jasmine.clock ()
|
||||
.uninstall ();
|
||||
});
|
||||
|
||||
it ('should verify signature using function retrieved timeout', () => {
|
||||
jasmine.clock ()
|
||||
.install ();
|
||||
const base_time = (new Date);
|
||||
jasmine.clock ()
|
||||
.mockDate (base_time);
|
||||
|
||||
const obj = { foo: 'bar' };
|
||||
const str = crypto.sign_object (obj, 'baz', { to: 100 });
|
||||
|
||||
@ -278,18 +258,9 @@ describe ('crypto helper', () => {
|
||||
const dec = crypto.verify_signature (str, 'baz', (info) => info.to);
|
||||
expect (obj)
|
||||
.toEqual (dec);
|
||||
|
||||
jasmine.clock ()
|
||||
.uninstall ();
|
||||
});
|
||||
|
||||
it ('verify_signature on almost timed out packet', () => {
|
||||
jasmine.clock ()
|
||||
.install ();
|
||||
const base_time = (new Date);
|
||||
jasmine.clock ()
|
||||
.mockDate (base_time);
|
||||
|
||||
const obj = { foo: 'bar' };
|
||||
const str = crypto.sign_object (obj, 'baz');
|
||||
|
||||
@ -298,16 +269,29 @@ describe ('crypto helper', () => {
|
||||
const dec = crypto.verify_signature (str, 'baz', 10);
|
||||
expect (obj)
|
||||
.toEqual (dec);
|
||||
|
||||
jasmine.clock ()
|
||||
.uninstall ();
|
||||
});
|
||||
|
||||
it ('should decode problematic token', () => {
|
||||
// eslint-disable-next-line max-len
|
||||
const str = 'wEJbzvUywiaiGWZUG6CtCXNkNmRGyVoi9icytpTe4gZhsb8Gk.5PZbhGL525mdV7EmYomTwUei6qULpLaZwSXy92eaUDNgbyXPHsr9dfUCeEBpTqmzuq3VtmmV43epUyWRoHocAsV3.2';
|
||||
const obj = crypto.decode_signed (str);
|
||||
expect (obj)
|
||||
.toEqual ({ id: 1 });
|
||||
});
|
||||
|
||||
it ('should automatically reencode b64 tokens', () => {
|
||||
// eslint-disable-next-line max-len
|
||||
const str = 'eyJpYXQiOjE1ODE0NDAwMTIyODgsIm9iaiI6eyJpZCI6MX19.24ZOsWrnfkNe%2FbM0r7DaVJMqE2bfn2aAM%2BZSzWeSf31OCTlXXNWD34RBL2X5v3UliYQ4IIsLNBFbaW9texPHug%3D%3D';
|
||||
const obj = crypto.decode_signed (str);
|
||||
expect (obj)
|
||||
.toEqual ({ id: 1 });
|
||||
});
|
||||
|
||||
it ('verify_signature on b64 string', () => {
|
||||
// eslint-disable-next-line max-len
|
||||
const str = 'eyJpYXQiOjE2MDkzNDQ4MDMyMjcsIm9iaiI6eyJpZCI6MX19.N762xuMaNbT%2Fqb0uTKST68BZgSnmNxXaHl4GY7iAKqaDDEwZn3biYfg5DgJ45QgPZrndchczDjUqLkyXoqw4KQ%3D%3D';
|
||||
const obj = crypto.verify_signature (str, 'baz');
|
||||
expect (obj)
|
||||
.toEqual ({ id: 1 });
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user