HMAC.finalize( word_array ) doesn't appear to update properly?
ramses0 opened this issue · comments
const triplesec = require('triplesec');
const HMAC = triplesec.HMAC;
...snip...
getSecretKey() {
let secret_key = new triplesec.WordArray( this.secret );
let plaintext = new triplesec.WordArray(
this.id + "|" + this.name
);
console.log( 'secret_key: ', secret_key );
console.log( 'plaintext: ', plaintext );
let hm = new HMAC( secret_key );
console.log( 'hm: ', hm );
let out = hm.finalize( plaintext );
console.log( 'out: ', out );
return out.to_hex().substring( 0, 10 );
}
let x = new module.exports( "one", "two", "three" );
console.log( x );
console.log( x.getSecretKey() );
console.log( '-----------------------------------------' );
let y = new module.exports( "four", "five", "six" );
console.log( y );
console.log( y.getSecretKey() );
Maybe this is a real dumb issue, but I'm finding it impossible to get the above code to work (simple HMAC signing).
{ id: 'one', name: 'two', secret: 'three' }
secret_key: WordArray { words: 'three', sigBytes: 20 }
plaintext: WordArray { words: 'one|two', sigBytes: 28 }
hm: HMAC {
key: WordArray { words: 'three', sigBytes: 20 },
hasher:
SHA512 {
_data: WordArray { words: [], sigBytes: 0 },
_nDataBytes: 128,
_hash: X64WordArray { sigBytes: 64, words: [Array] } },
hasherBlockSize: 32,
hasherBlockSizeBytes: 128,
_oKey: WordArray { words: 'three', sigBytes: 128 },
_iKey: WordArray { words: 'three', sigBytes: 128 } }
out: WordArray {
words:
[ 1547129211,
439626697,
306711733,
2734092130,
-1219207254,
357078697,
-1089194041,
580722509,
-157960372,
4031738300,
1144976117,
79357941,
1308807098,
4134728090,
446849896,
-2016523090 ],
sigBytes: 64 }
5c37517b1a
-----------------------------------------
{ id: 'four', name: 'five', secret: 'six' }
secret_key: WordArray { words: 'six', sigBytes: 12 }
plaintext: WordArray { words: 'four|five', sigBytes: 36 }
hm: HMAC {
key: WordArray { words: 'six', sigBytes: 12 },
hasher:
SHA512 {
_data: WordArray { words: [], sigBytes: 0 },
_nDataBytes: 128,
_hash: X64WordArray { sigBytes: 64, words: [Array] } },
hasherBlockSize: 32,
hasherBlockSizeBytes: 128,
_oKey: WordArray { words: 'six', sigBytes: 128 },
_iKey: WordArray { words: 'six', sigBytes: 128 } }
out: WordArray {
words:
[ 1547129211,
439626697,
306711733,
2734092130,
-1219207254,
357078697,
-1089194041,
580722509,
-157960372,
4031738300,
1144976117,
79357941,
1308807098,
4134728090,
446849896,
-2016523090 ],
sigBytes: 64 }
5c37517b1a
I've been through the project README's, the CODA docs, the hmac.iced code, etc. and am able to get EXACTLY the same thing working via node's built-in crypto (which unfortunately doesn't work in the browser). I'm smart enough about crypto that I know I should be using HMAC for digest validation (not MD5/SHA) but what is going on here? Why isn't "triplesec" working the way I think it should? I've already got it working it working with triplesec.encrypt, triplesec.decrypt, new triplesec.Buffer( key / ciphertext ), etc. but I am going mad trying to figure out how I'm incorrectly calling this HMAC function!!?
$ yarn list | grep triple
warning package.json: No license field
warning No license field
├─ triplesec@3.0.26
const crypto = require('crypto');
// server side only!!! :_(
getSecretKeyNodeServer() {
const hmac = crypto.createHmac( 'sha256', this.secret );
hmac.update( this.id + "|" + this.name );
let out = hmac.digest('hex').substring(0,10);
return out;
}
let z = new module.exports( "one", "two", "three" );
console.log( z );
console.log( z.getSecretKeyNodeServer() );
console.log( '-----------------------------------------' );
let a = new module.exports( "four", "five", "six" );
console.log( a );
console.log( a.getSecretKeyNodeServer() );
...and the "somewhat proper" output I'm expecting for use of crypto / HMAC / signing.
{ id: 'one', name: 'two', secret: 'three' }
8aaa5db897
-----------------------------------------
{ id: 'four', name: 'five', secret: 'six' }
7a395acafe
```
works fine for me:
const triplesec = require('triplesec');
const HMAC = triplesec.HMAC;
const WordArray = triplesec.WordArray;
const crypto = require('crypto');
let key = "this is my key";
let payload = "this is the payload";
let hmac1 = crypto.createHmac("SHA512", key);
console.log(hmac1.update(payload).digest('hex'));
let hmac2 = new HMAC(WordArray.from_utf8(key));
console.log(hmac2.finalize(WordArray.from_utf8(payload)).to_hex())
Outputs:
2a40ed59a986063b3e4638bbf61ccab1897521975cd87039b908376838dff82dbb27fa242be73b71e51f258f570d23f7c5d40d99fac06b8ea6777088f1bd42e2
2a40ed59a986063b3e4638bbf61ccab1897521975cd87039b908376838dff82dbb27fa242be73b71e51f258f570d23f7c5d40d99fac06b8ea6777088f1bd42e2
WordArray.from_utf8(key)
...this was the key! I was using new triplesec.WordArray( "text here" )
instead of treating WordArray as a factory. :-(
Can I convert this into a bug report then? "No examples of how to use WordArray or HMAC in the documentation?" ...especially WordArray.from_utf8(...)
seems like a critical thing to mention for proper use of the crypto lib.
https://www.npmjs.com/package/triplesec
In addition, if the object is "newed" incorrectly (ie: as above, new WordArray( "javascript string" )
) that should likely warrant an error / exception. It was only when I started doing more detailed testing and finding that basically everything was an HMAC of undefined
that I dug into it more.
If this stays open for longer than a week, I'll maybe try and get a PR up for documentation examples, but for now, thanks a bunch for pointing me in the right direction!
Sure