Search code examples
javascriptnode.jscryptojsbase64url

nodejs crypto and CryptoJS giving different base64(sha256(data)) outputs


I have a node server and a react-native app. On the node server, all cryptography is done using the crypto module. On the react-native app, all cryptography is done through the crypto-js library because crypto is not available.

I have this sample code on Repl.it - https://repl.it/repls/UprightExtraneousDesigner#index.js

Copy-pasted to prevent link decay:

const crypto = require("crypto");
const base64url = require("base64url");
const CryptoJS = require("crypto-js");

let publicKey = "6rjJnHqufRdGq7LxP6UyJEDbE84YRUKyZNYc27rUBqQZ";

const hash1 = crypto.createHash("sha256").update(Buffer.from(publicKey)).digest();
const hash2 = CryptoJS.SHA256(publicKey);

const kid1 = base64url.encode(hash1)

const kid2 = CryptoJS.enc.Base64.stringify(hash2);

console.log("KID1: ", kid1);
console.log("KID2: ", kid2);

But, for some reason, they're giving me slightly different results. The output im getting is

KID1:  qlm-6fOvD0F2qxOYDCvOkkohHfXL6nd_SpBDsBOWawE
KID2:  qlm+6fOvD0F2qxOYDCvOkkohHfXL6nd/SpBDsBOWawE=

There's three differences here:

  1. KID1 has a - at index 3, whereas KID2 has a +
  2. KID1 has an _ at index 31, whereas KID2 has a /
  3. KID1 has no padding, whereas KID2 has padding at the end

Due to the discrepancies here, I'm getting problems on my server. Can someone explain to me why this is happening and how can I fix it? I think it has something to do with the characters being used in the different base64 implementations, but im not sure how to fix that.


Solution

  • Do the base64 conversion using the tools provided by the Node.js crypto module.

    const hash1 = crypto.createHash("sha256").update(Buffer.from(publicKey)).digest('base64');