Hi all, I have a problem with the generation of a hash. I have a Javascript code that takes the body of a request, passes it to a string and then generates a hash. I need to pass the code to Elixir, but the results do not match. I share the code with you:
JS
import sha256 from 'crypto-js/sha256';
import Base64 from 'crypto-js/enc-base64';
const body = "my body"
const hashDigest = sha256(body);
const digest = Base64.stringify(hashDigest)
console.log("Digest:", digest);
Result: "IZ2yn/XIIEdwXSkGAK/256XFSNMy33gr0zRZoo+pe/c="
Elixir
def compute_digest(body) do
body
|> Jason.encode!()
|> (&:crypto.hash(:sha256, &1)).()
|> Base.encode64()
|> IO.inspect(label: "Digest")
end
Result: "7om2lOXEa2byLhn1M19iEf9KA6DdnljHD6BMdA8IdLc="
Hello valid @josevalim, Yes, they are the same. I don’t know if it’s because with Elixir the result of Jason.encode!(“hello”) is "\"hello\"" and with JS it’s just “hello”.
Anyway, same issue: “"hello"” is not the same as “hello, so it can’t be the same hash.
As stated above, make sure you’re doing the same encodings in both languages
A very important thing to keep in mind is JSON key order. Neither the JSON spec nor the Elixir maps you generally encode to JSON have any guaranteed key order, so when you write it out to a string you may get different actual strings before the encoding. That may not matter for you use case but it’s a common issue if you expect strict equality with larger or more complex JSON strings.
Yes, thank you, yesterday I was able to identify that this is the problem. When getting the body it is changing the odern of the keys. Actually the string transformation that the Jason.encode!/1 does does not affect the hash generation. Thanks for the help.