Search code examples
javascriptcryptographycryptojs

Why does update in crypto-js output differ from NodeJS' crypto when updating IntArray


I'm trying to refactor something that used NodeJS' crypto into something that uses crypto-JS but I'm running into some issue when I'm updating the hash content.

Here's the original hash that I wanted to replace:

const original_hash = crypto.createHash('sha512').update(someString).update(someIntArray).digest()

And here's the new hash using crypto-js:

const new_hash = CryptoJS.algo.SHA512.create().update(someString).update(someIntArray).finalize();

Does anyone know why the 2nd update is making such differences? An example of the someIntArray would be Int8Array(6) [ 26, -50, -59, -118, -101, 33 ]


Solution

  • This is because CryptoJS.update() does not support Int8Array as input, see core.js#L561.

    You can convert Int8Array to hex string, and parse it using CryptoJS.enc.Hex.parse().

    const int8ArrayToHex = (int8Array) => {
        // x << 24 >>> 24 converts int8 to uint8
        return Array.from(int8Array).map(x => (x << 24 >>> 24).toString(16).padStart(2, '0')).join('')
    }
    
    let hex = int8ArrayToHex(new Int8Array([ 26, -50, -59, -118, -101, 33 ]))
    console.log(hex) // 1acec58a9b21
    
    const new_hash = CryptoJS.algo.SHA512.create().update(CryptoJS.enc.Hex.parse(hex)).finalize().toString()
    console.log(new_hash) // 3c1d419bfcd4...
    

    Demo

    Result can be verified here: CyberChef: From Decimal -> SHA512