cryptonite: Why is `digestFromByteString` Nothing?
I'm trying to verify a signature on a web request. I need to compute an HMAC with the SHA256 hash function using my secret as the key and a signed payload as the message, then compare that with the signature.
The signature looks like this:
0d586561d8f896e52d5c4a2147609fdf74eb72e7bcb3a3756b89fcbef88a94b3
It seems like cryptonite
is the right library for this, so I'm using hmac from Crypto.MAC.HMAC. Here's what I have so far:
case digestFromByteString signature of
Nothing -> return False
Just signatureDigest ->
return $ signatureDigest `constEq` hmacGetDigest (hmac secret signedPayload :: HMAC SHA256)
Visually the digest and the signature look the same. If I convert both sides to strings, the strings are equal.
show hmacHash == T.unpack (T.decodeUtf8 signature) -- This is True!
But I can't even get so far as constEq
because when I use digestFromByteString
to convert the signature string into a digest, it fails. Why?
(Also if I'm barking up the wrong tree on anything else, please let me know.)
I finally found out the answer from a Google search that lead to an old Gitter discussion.
Even though digestFromByteString
will take a hex-encoded ByteString, it doesn't know what to do with it. I had to use memory
's convertFromBase
to convert from base16.
I added this before my conversion to the digest, and now everything works!
case convertFromBase Base16 hexSignature of
Left err -> return False
Right signature -> ...
(Leaving this unanswered in case anyone who actually knows about cryptonite can explain the "why" better...)