Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error with HMAC and newlines in R "digest" package

Tags:

r

hmac

I am attempting to implement R code to interface with Amazon's Alexa Web Information Service. The authentication system requires HMAC hashing of text against a secret key, but there seems to be a problem with the "digest" package when the text contains newlines.

Minimal example in R:

library(digest)
hmac("foo", "Hello", algo="sha256")

returns fa687477a49ebadb72eb1103db6128061437a2501db7ee7f0cbbb79ceaa2fcfc, while

hmac("foo", "Hello\nGoodbye", algo="sha256")

returns eaf58b106ffdbb4af976b6b87e14d231e090f7bc144f0b56f06980c827444288.

If I check against http://www.freeformatter.com/hmac-generator.html, the first case gives the same hash, but the second gives 967b28392b2ddc871bb69417e916fa619c935840cc2b9507ecf4da3f748bd1ba.

Am I missing something obvious?

Thanks in advance!!!

like image 791
NumerousHats Avatar asked Dec 11 '22 05:12

NumerousHats


2 Answers

So, while MrFlick did answer my specific question, the real issue was deeper. The whole question was prompted by a disagreement between Perl's hmac_sha256_base64() and R.

It turned out that I was using R incorrectly. hmac() returns hex code, not base64, so an additional step is needed. However, it seems that the base64() function in RCurl requires a vector of bytes, not a concatenated string. I illustrate below.

What I was doing (WRONG):

require(digest)
require(RCurl)

> hmac("foo", "Hello", algo="sha256")
[1] "fa687477a49ebadb72eb1103db6128061437a2501db7ee7f0cbbb79ceaa2fcfc"

> base64(hmac("foo", "Hello", algo="sha256"))
[1] "ZmE2ODc0NzdhNDllYmFkYjcyZWIxMTAzZGI2MTI4MDYxNDM3YTI1MDFkYjdlZTdmMGNiYmI3OWNlYWEyZmNmYw=="
attr(,"class")
[1] "base64"

What I should have done (CORRECT):

> hmac("foo", "Hello", algo="sha256", raw = T)
[1] fa 68 74 77 a4 9e ba db 72 eb 11 03 db 61 28 06 14 37 a2 50 1d b7 ee 7f 0c bb b7 9c ea a2 fc fc

> base64(hmac("foo", "Hello", algo="sha256", raw = T))
[1] "+mh0d6Seutty6xED22EoBhQ3olAdt+5/DLu3nOqi/Pw="
attr(,"class")
[1] "base64"

Rather different, no?

The latter agrees with the Perl, and (more importantly) it actually authenticates correctly on Amazon Web Services. :-)

like image 191
NumerousHats Avatar answered Jan 17 '23 19:01

NumerousHats


Welcome to the wonderful world of newlines! It appears that the website uses windows style line endings when you include a newline in the text. So you can get that "967b" value if you do

hmac("foo","Hello\r\nGoodbye",algo="sha256")
# [1] "967b28392b2ddc871bb69417e916fa619c935840cc2b9507ecf4da3f748bd1ba"

I'm guessing you might be on a Mac or a linux machine. I think the \n character is supposed to resolve to the correct value depending on OS. Perhaps doing

hmac("foo","Hello\x0D\x0AGoodbye",algo="sha256")

might be better to be explicit about the line ending you need to do in the file on all systems.

like image 22
MrFlick Avatar answered Jan 17 '23 17:01

MrFlick