Home > Back-end >  CryptoJs SHA256 to Base64url wrong value
CryptoJs SHA256 to Base64url wrong value

Time:06-15

I have the following code:

import Base64url from "crypto-js/enc-base64url"
import SHA256 from "crypto-js/sha256";

//... 

const codeVerifier = "test-value";
const hashed = SHA256(codeVerifier);


console.log({ sha256: hashed.toString() });
// output: sha256: 5b1406fffc9de5537eb35a845kc99521f26fba0e772d58b42e09f4221b9e043ae

console.log({ base64: Base64url.stringify(hashed) })
// output: base64: WxQG__yd5VN-s1qEXJlSHyb7oOdy1YtC4J9CIbngQ64

// expected: base64: NWIxNDA2ZmZmYzlkZTU1MzdlYjM1YTg0NWM5OTUyMWYyNmZiYTBlNzcyZDU4YjQyZTA5ZjQyMjFiOWUwNDNhZQ

As you can see the output that I'm getting is incorrect (I used an online base64url generator to validate, such as this one). I'm guessing I'm doing something wrong here, but I can't see it. I read the documentation and couldn't find anything.

I've prepared a small codesandbox if it helps.

CodePudding user response:

What you are experiencing is related to the CryptoJS package since I saw that you are using crypto-js/enc-base64url inside your codebox example.

Objects in CryptoJS are WordArray types, meaning that when you call toString() on such an object, you get a Hex-encoded string of that binary object. However, if you print result.toString(CryptoJS.enc.Base64) then you get the Base64-encoded string of the binary result.

If you take your assigned variable and directly encode it to Base64, then it is probably assumed that a is already a string (e.g. UTF-8 encoded). The online calculators that you are using for validation don't know that it is Hex-encoded.

I hope that answers your question.

CodePudding user response:

So after searching a bit more, here is what I did:

const codeVerifier = "test-value";
const hashed = SHA256(codeVerifier);

// parse to utf-8-encoded data
const utf8parsed = Utf8.parse(hashed.toString());

console.log({ sha256: hashed.toString() });
// output: sha256: 5b1406fffc9de5537eb35a845kc99521f26fba0e772d58b42e09f4221b9e043ae

console.log({ base64: Base64url.stringify(utf8parsed) });
// correct output!

Thanks to others that helped (@ZombieChowder)!

CodePudding user response:

Since you want base64 encoded hex string of the hash and crypto-js library's base64 encoder doesn't accept strings, you can use btoa.

btoa(hashed.toString())

But than might not what you want, if you actually need the Base64url variant.

  • Related