简体   繁体   中英

HMAC_SHA256 generating incorrect signature for AWS example

I am working on the example listed here

I am using the below HMAC_SHA256 code provided by OpenSSL to sign URL's that I pass into it.

#include <openssl/evp.h>
#include <openssl/hmac.h>

unsigned char* hmac_sha256(const void *key, int keylen,
                       const unsigned char *data, int datalen,
                       unsigned char *result, unsigned int* resultlen)
{
    return HMAC(EVP_sha256(), key, keylen, data, datalen, result, resultlen);
}

The code I have that sets up the example is the following:

const unsigned char* test = "GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01";
unsigned char* result = hmac_sha256("1234567890",strlen("1234567890"),test,strlen((char*)test),NULL,NULL);
char dump[5] = {0};
sprintf(dump, "%02x", result[0]);
printf("%s",dump);

The problem is that I get 8F as an ouput when I am supposed to be getting 6a for "j". I get a warning about signedness of the variable test and I think that is the reason I am not getting the correct output. I have looked around to see how I could initalize the unsigned char* to equal the URL given in the example but it seems like you cannot set literals to unsigned char*'s.

How would I go about correctly unsigning the string and passing it correctly to hmac_sha256()?

your code works. There is nothing wrong with it. First, the code, then I will explain.

ubuntu@ubuntu:~$ cat abc.c 
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <stdio.h>
#include <string.h>

unsigned char* hmac_sha256(const void *key, int keylen,
                       const unsigned char *data, int datalen,
                       unsigned char *result, unsigned int* resultlen)
{
    return HMAC(EVP_sha256(), key, keylen, data, datalen, result, resultlen);
}

int main()
{
const char* value = "GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01";
const char* key = "1234567890";

unsigned char* result = hmac_sha256(key,strlen(key),value,strlen(value),NULL,NULL);
printf("%s", result);
}


ubuntu@ubuntu:~$ echo -ne "GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&AssociateTag=mytag-20&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers%2CReviews&Service=AWSECommerceService&Timestamp=2014-08-18T12%3A00%3A00Z&Version=2013-08-01"  |  openssl dgst -sha256 -hmac "1234567890"
(stdin)= 8fb6d93342d767d797799aee4ea5a6d8322f0d8554537c313cfa69fa25f1cd07
ubuntu@ubuntu:~$ gcc abc.c -lcrypto -o abc
ubuntu@ubuntu:~$ ./abc | od -tx1
0000000 8f b6 d9 33 42 d7 67 d7 97 79 9a ee 4e a5 a6 d8
0000020 32 2f 0d 85 54 53 7c 31 3c fa 69 fa 25 f1 cd 07
0000040
ubuntu@ubuntu:~$ ./abc | base64 
j7bZM0LXZ9eXeZruTqWm2DIvDYVUU3wxPPpp+iXxzQc=

Your program produces "8f b6 d9 33 42 d7 67 d7 97 79 9a ee 4e a5 a6 d8 32 2f 0d 85 54 53 7c 31 3c fa 69 fa 25 f1 cd 07" And you believe 8f is wrong, because it should start with j as in "j7bZM0LXZ9eXeZruTqWm2DIvDYVUU3wxPPpp+iXxzQc=" But you have not done a base64 on your output.

Converting "8f b6 d9 33 42 d7 67 d7 97 79 9a ee 4e a5 a6 d8 32 2f 0d 85 54 53 7c 31 3c fa 69 fa 25 f1 cd 07" to base64 was shown here using the base64 program, but in your case, you would want to use it progmatically.

This may help you: How do I base64 encode (decode) in C?

TL;DR: You did nothing wrong, you just forgot one extra step.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM