HMAC_SHA256为AWS示例生成错误签名

时间:2017-05-02 17:24:01

标签: c amazon-web-services

我正在研究列出的here

示例

我使用OpenSSL提供的以下HMAC_SHA256代码来签署我传入的URL。

#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);
}

我设置示例的代码如下:

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);

问题是,当我应该为#34; j&#34;获得6a时,我得到8F作为输出。我收到关于变量测试签名的警告,我认为这是我没有得到正确输出的原因。我环顾四周看看如何将unsigned char *初始化为等于示例中给出的URL,但似乎你不能将文字设置为unsigned char *&#39; s。

我如何正确地取消签名并将其正确传递给hmac_sha256()?

1 个答案:

答案 0 :(得分:2)

您的代码有效。 没有什么问题。 首先是代码,然后我会解释。

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=

您的节目制作“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” 并且您认为8f是错误的,因为它应该以j开头,如“j7bZM0LXZ9eXeZruTqWm2DIvDYVUU3wxPPpp + iXxzQc =” 但是你没有在输出上做过base64。

转换“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”这里使用base64程序显示到base64,但是你的情况,你会想要以进步的方式使用它。

这可能对您有所帮助: How do I base64 encode (decode) in C?

TL; DR: 你没有做错任何事,你只是忘记了一步。