From 71b317bccb3f1082d93f5d11e16d5119fdf9c955 Mon Sep 17 00:00:00 2001 From: Johan Nordberg Date: Thu, 25 Jan 2018 12:15:17 +0100 Subject: [PATCH 1/4] Add test for hashMessage --- src/index.ts | 2 +- test/index.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index a13f1a5..bbeff88 100644 --- a/src/index.ts +++ b/src/index.ts @@ -77,7 +77,7 @@ class ValidationError extends Error { * * @returns bytes to be signed or validated. */ -function hashMessage(timestamp: string, account: string, method: string, +export function hashMessage(timestamp: string, account: string, method: string, params: string, nonce: Buffer): Buffer { const first = createHash('sha256') first.update(timestamp) diff --git a/test/index.ts b/test/index.ts index fffbbf0..9656902 100644 --- a/test/index.ts +++ b/test/index.ts @@ -4,7 +4,7 @@ import {randomBytes} from 'crypto' import * as fetch from 'node-fetch' import {PrivateKey, Client, utils, Signature} from 'dsteem' -import {sign, validate, JsonRpcRequest, VerifyMessage, SignedJsonRpcRequest} from './../src/' +import {sign, validate, JsonRpcRequest, VerifyMessage, SignedJsonRpcRequest, hashMessage} from './../src/' const dummyVerify: VerifyMessage = async (message: Buffer, signatures: string[], account: string) => {} @@ -258,3 +258,15 @@ describe('rpc auth', function() { }) }) + +describe('hashMessage', function() { + + const expected = Buffer.from('04d1b962e951babf44b1bb161d9ba97aa526aa633bf31505c2ccb593a895ac42', 'hex') + + it('creates correct message', function() { + const nonce = Buffer.from('29a0132f4b950adb', 'hex') + const hash = hashMessage('2018-01-15T12:34:56Z', 'foo', 'bar.baz', 'WyJxZXgiXQo=', nonce) + assert.deepEqual(hash, expected) + }) + +}) From 7c9dbeb8ee87b139f82a6deece01f65233732377 Mon Sep 17 00:00:00 2001 From: Johan Nordberg Date: Thu, 25 Jan 2018 12:48:11 +0100 Subject: [PATCH 2/4] Compare expected hash with hex string for readability --- test/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/index.ts b/test/index.ts index 9656902..d9fd678 100644 --- a/test/index.ts +++ b/test/index.ts @@ -261,12 +261,12 @@ describe('rpc auth', function() { describe('hashMessage', function() { - const expected = Buffer.from('04d1b962e951babf44b1bb161d9ba97aa526aa633bf31505c2ccb593a895ac42', 'hex') + const expected = '04d1b962e951babf44b1bb161d9ba97aa526aa633bf31505c2ccb593a895ac42' it('creates correct message', function() { const nonce = Buffer.from('29a0132f4b950adb', 'hex') const hash = hashMessage('2018-01-15T12:34:56Z', 'foo', 'bar.baz', 'WyJxZXgiXQo=', nonce) - assert.deepEqual(hash, expected) + assert.equal(hash.toString('hex'), expected) }) }) From 63182ffebd3754cd4ffd9fe6d378d884d920899a Mon Sep 17 00:00:00 2001 From: Johan Nordberg Date: Thu, 25 Jan 2018 12:48:40 +0100 Subject: [PATCH 3/4] Use sjcl to generate message hashes --- src/index.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index bbeff88..0915f7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,8 +3,8 @@ * @author Johan Nordberg */ -import {hexify, PrivateKey} from '@steemit/libcrypto' -import {createHash, randomBytes} from 'crypto' +import {hexify, PrivateKey, sjcl} from '@steemit/libcrypto' +import {randomBytes} from 'crypto' /** * Signing constant used to reserve opcode space and prevent cross-protocol attacks. @@ -79,18 +79,18 @@ class ValidationError extends Error { */ export function hashMessage(timestamp: string, account: string, method: string, params: string, nonce: Buffer): Buffer { - const first = createHash('sha256') + const first = new sjcl.hash.sha256() first.update(timestamp) first.update(account) first.update(method) first.update(params) - const second = createHash('sha256') - second.update(K) - second.update(first.digest()) - second.update(nonce) + const second = new sjcl.hash.sha256() + second.update(sjcl.codec.arrayBuffer.toBits(K.buffer)) + second.update(first.finalize()) + second.update(sjcl.codec.arrayBuffer.toBits(nonce.buffer)) - return second.digest() + return Buffer.from(sjcl.codec.arrayBuffer.fromBits(second.finalize())) } /** From 715d7570b840dc08f46aca037ddc0630b7360613 Mon Sep 17 00:00:00 2001 From: Johan Nordberg Date: Thu, 25 Jan 2018 13:14:24 +0100 Subject: [PATCH 4/4] Fix Buffer to ArrayBuffer conversion --- src/index.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0915f7c..c4d10c1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,6 +66,11 @@ class ValidationError extends Error { } +function bufferToBits(b: Buffer) { + const ab = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength) + return sjcl.codec.arrayBuffer.toBits(ab) +} + /** * Create request hash to be signed. * @@ -86,9 +91,9 @@ export function hashMessage(timestamp: string, account: string, method: string, first.update(params) const second = new sjcl.hash.sha256() - second.update(sjcl.codec.arrayBuffer.toBits(K.buffer)) + second.update(bufferToBits(K)) second.update(first.finalize()) - second.update(sjcl.codec.arrayBuffer.toBits(nonce.buffer)) + second.update(bufferToBits(nonce)) return Buffer.from(sjcl.codec.arrayBuffer.fromBits(second.finalize())) }