use base58 encoding for signatures
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Timo Hocker 2020-12-30 17:16:29 +01:00
parent 142e9ec458
commit 612686a224
4 changed files with 2068 additions and 2726 deletions

View File

@ -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
};

View File

@ -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",

View File

@ -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
// 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 });
});
});

4664
yarn.lock

File diff suppressed because it is too large Load Diff