keybase / triplesec

Triple Security for the browser and Node.js
https://keybase.io/triplesec
MIT License
399 stars 47 forks source link

HMAC.finalize( word_array ) doesn't appear to update properly? #62

Open ramses0 opened 6 years ago

ramses0 commented 6 years ago
       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
maxtaco commented 6 years ago

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())
maxtaco commented 6 years ago

Outputs:

2a40ed59a986063b3e4638bbf61ccab1897521975cd87039b908376838dff82dbb27fa242be73b71e51f258f570d23f7c5d40d99fac06b8ea6777088f1bd42e2
2a40ed59a986063b3e4638bbf61ccab1897521975cd87039b908376838dff82dbb27fa242be73b71e51f258f570d23f7c5d40d99fac06b8ea6777088f1bd42e2
ramses0 commented 6 years ago
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!

maxtaco commented 6 years ago

Sure