2

I am using the crypto module of node.js to generate a SHA256 hash like this:

const key = crypto.createHmac('sha256', data).digest('hex');

Now, tweetnacl throws the error: bad key size when the key is passed in the secretbox:

nacl.secretbox(data, Rnonc, key);

The parameters are converted into Uint8Array since the secretbox requires arguments to be Uint8Array.

The error: bad key size is throw from here in tweetnacl since the crypto_secretbox_KEYBYTES is defined as 32 here. The problem is the key returned from crypto is in not 32 bytes size.

I have searched SO and relevant sites, but couldn't find any feasible solution but according to this - the SHA256 hash converted to hex produces:

32 separate hexadecimal numbers (or 32 bytes)

How can I generate a SHA256 key of 32 bytes in order to avoid this error using node.js? Is there something I am doing wrong in generating the SHA256 hash?

Abrar
  • 6,874
  • 9
  • 28
  • 41
  • Can you please try this? `const key = crypto.createHmac('sha256', data).digest('base64');` Also try to print the key inside the function and try to process it locally once. – Arihant Aug 23 '18 at 05:57
  • I tried with `crypto.createHmac('sha256', data).digest('base64')`, still getting `bad key size` – Abrar Aug 23 '18 at 06:01
  • 1
    There are multiple calls for `checkLengths`. Can you please point the line where you are getting this error? – Arihant Aug 23 '18 at 06:36
  • I am getting it from [here](https://github.com/dchest/tweetnacl-js/blob/master/nacl.js#L954) – Abrar Aug 23 '18 at 06:40
  • Can you try adding a `cosole.log(k); cosole.log(k.length);` inside the function and see what k is? You may get a clue .. – Arihant Aug 23 '18 at 08:04
  • For `key` I get a `Uint8Array` array as output like this `[98, 87, 122, 87, 77, 111, 83, 43, 83, 107, 101, 54, 101, 117, 120, 75, 78....`, of length `44`. Any idea how can I convert it to 32 bytes of size? – Abrar Aug 23 '18 at 16:27
  • 1
    This link may help you. https://stackoverflow.com/questions/44796371/sha256-with-byte32-using-cryptojs – Arihant Aug 23 '18 at 16:48

1 Answers1

2

The following code snippet solved the issue of generating a 32 bytes SHA256 hash avoiding the bad key size error thrown from tweetnacl.js:

const CryptoJS = require('crypto-js');

let hash   = CryptoJS.SHA256('hello world');
let buffer = Buffer.from(hash.toString(CryptoJS.enc.Hex), 'hex');
let array  = new Uint8Array(buffer);

This always generates a Uint8Array of 32 bytes size. Notice here I had to use the crypto-js module although I preferred to use the native crypto module but I guess I would just use it for now as it is a working solution.

Thanks to @Arihant for pointing to this (check the comment section)

Abrar
  • 6,874
  • 9
  • 28
  • 41