Andy
Andy

Reputation: 1092

How to create SHA256 hash from byte array in JavaScript?

I am trying to reproduce Python's hashlib.sha256 in JavaScript. However, the resulting hashes are different.

In Python the hash is calculated correctly:

In [1]: import hashlib
   ...: from binascii import unhexlify

In [2]: a = "56687282f0f3c1ca76132c6c2fee44ee93a0b3251740719ea3e33b8366d86615"

In [3]: hashlib.sha256(unhexlify(a)).hexdigest()
Out[3]: 'd7928286f70bf6f89802d9b13bed2aae9c65609133dcd37ae03345b4ee2e8731'

Using the CryptoJS library in JavaScript:

var a = "56687282f0f3c1ca76132c6c2fee44ee93a0b3251740719ea3e33b8366d86615";
for (var bytes = [], c = 0; c < a.length; c += 2){
    bytes.push(parseInt(a.substr(c, 2), 16));
}
CryptoJS.SHA256(bytes).toString();

"4ea5c508a6566e76240543f8feb06fd457777be39549c4016436afda65d2330e"

Since JavaScript's bytes and Python's unhexlify(a) are the same, the CryptoJS.SHA256 seems to produce a different hash.

Which SHA256-function in JavaScript would be compatible for hashing byte arrays?

Upvotes: 1

Views: 4383

Answers (1)

Caerbannog
Caerbannog

Reputation: 825

The problem is not CryptoJS.SHA256, it is the way that you convert from hex to bytes in Javascript.

CryptoJS provides a CryptoJS.enc.Hex.parse() (doc) method that works for your example:

const CryptoJS = require('crypto-js');
const a = '56687282f0f3c1ca76132c6c2fee44ee93a0b3251740719ea3e33b8366d86615';
CryptoJS.SHA256(CryptoJS.enc.Hex.parse(a)).toString();
// Output: 'd7928286f70bf6f89802d9b13bed2aae9c65609133dcd37ae03345b4ee2e8731'

The incorrect assumption in your code is that an array of numbers is a valid input to hash. Actually, CryptoJS inputs should be of type WordArray. And they look like this:

CryptoJS.enc.Hex.parse(a);
/* Output:
{
  words: [
    1449685634,
    -252460598,
    1980968044,
    804144366,
    -1818184923,
    390099358,
    -1545389181,
    1725457941
  ],
  sigBytes: 32
}
*/

Upvotes: 3

Related Questions