Reputation: 61
I am following the examples given on this page and I end up getting the correct signature using the details given here .
My problem is I get the signature ced6826de92d2bdeed8f846f0bf508e8559e98e4b0199114b84c54174deb456c
correctly but, as soon as I use the same methods and change the variables for the GET example on this page, it gives me signature c2eb7ddb12cb2c46489fdf97947e68b24c3716
instead of f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41
.
This is C++ code using openSSL for HMAC and SHA256 hashing.
The Test function
void Test3()
{
std::string date = std::string("20130524");
std::string region = std::string("us-east-1");
std::string service = std::string("s3");
std::string request = std::string("aws4_request");
std::string key = std::string("AWS4wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
unsigned char* signingKey = EncodeHMACSHA256_2(EncodeHMACSHA256_2(EncodeHMACSHA256_2(EncodeHMACSHA256_2((unsigned char*)key.c_str(), &date), ®ion), &service), &request);
std::string stringToSign = std::string();
stringToSign.append("AWS4-HMAC-SHA256\n");
stringToSign.append("20130524T000000Z\n");
stringToSign.append("20130524/us-east-1/s3/aws4_request\n");
stringToSign.append("7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972");
// Create signature
unsigned char* signature = EncodeHMACSHA256_2(signingKey, &stringToSign);
// to hex
std::string sigHex = ToHex(signature);
}
HMAC function
unsigned char* EncodeHMACSHA256_2(unsigned char* key, std::string* value)
{
const unsigned char* dataToHash = (unsigned char*)value->c_str();
// Initialise HMAC
HMAC_CTX HMAC;
unsigned int hmaclength = 64; // Length of the resulting SHA256 hash
unsigned char* hmachash = (unsigned char*)malloc(sizeof(char) * hmaclength);
memset(hmachash, 0, hmaclength);
// Digest the key and message using SHA256
HMAC_CTX_init(&HMAC);
HMAC_Init(&HMAC, key, strlen((char*)key), EVP_sha256());
HMAC_Update(&HMAC, dataToHash, strlen((char*)dataToHash));
HMAC_Final(&HMAC, hmachash, &hmaclength);
HMAC_CTX_cleanup(&HMAC);
return hmachash;
}
Hex Function
std::string ToHex(unsigned char* value)
{
int len = strlen((char*)value);
std::stringstream stream;
for (int i = 0; i < len; i++)
{
char tmpStr[3] = { 0 };
int res = sprintf(tmpStr, "%02x", value[i]);
stream << tmpStr;
}
return stream.str();
}
Upvotes: 2
Views: 1487
Reputation: 521
We can alternatively use vector
if you are using C++11. The pros of using vector
is you dont have to keep track of the memory deallocation.
I have an implementation of the same here - HMAC SHA256 in C++ (DynamoDB)
Upvotes: 0
Reputation: 61
The HMAC function was causing the problem, I was converting the unsigned char * to a char * and taking that length which, would end as soon as it hit a zero thus giving a different length. Changed the function to include a length for the key and value.
The HMAC length was changed from 64 to 32 and passed 32 into the function for the key length.
To warn other people on the examples given on Amazon website, beware that the string to sign date is not in ISO format its the same date and time that you pass in the date header i.e. Mon, 06 October etc...
Upvotes: 4