Amazon, Product Advertising API, signing request (C++)
I got stuck in trying to perform request to Amazon Product Advertising API with C++. Actually, I'm not sure that problem lying in language rather then in my misreading or misunderstanding of documentation. Let me provide quote from documantation:
Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm using the string above with this example AWS secret key: 1234567890. For more information about this step, see documentation and code samples for your programming language.
So far as I understood I need to perform SHA256 hashing on request string, encode it with Base64 and then additionally URL encode some characters (like '+' eg). However, when I try to do those steps with for example some online services for HMACSHA256 and Base64 for this string from documentation:
GET webservices.amazon.com /onca/xml AWSAccessKeyId=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
I'm getting completely different signature (not the same as provided in documentation). Signature from documantation:
j7bZM0LXZ9eXeZruTqWm2DIvDYVUU3wxPPpp+iXxzQc=
Services that I'm using: HMACSHA256 and Base64. My signature:
YzZhNzMwZGIwMDhmMmY4NjhiOTYyNTNiNjhmMGE5YjY2MWNlOGRhYzMxOTczZDM5Yjk4YzM5MmE4MTNmNmZkOQ==
I also have tryed to perform the same steps in my C++ code, but get different signature. Basically, my question is: what exactly I'm doing wrong? Did I misunderstood algorithm's steps or there is some additional steps that I'm not aware of or something else?
If somebody already did something similar in C++ and can provide some snippets of code I will be really gratefull. Any point to my mistakes will be highly appreciated too. If you miss some information from my side - please point it out in comment and I will provide it as soon as possible.
I finally managed to get the solution. I wouldn't say that problem was in my misreading or misunderstanding of documentation, rather the some general lack of knowledge about hashing/signing something. Basically, problem was that I wasn't taking digest of HMACSHA256. After some digging into examples for another languages, I found this reference to digest in Python sample. There is my solution for any future Googlers over here :)
std::string generate_hmac256bit_hash(const char *message, const char *key_buf) {
unsigned char* digest = HMAC(EVP_sha256(), key_buf, strlen(key_buf), (unsigned char*)message, strlen(message), NULL, NULL);
std::string signature = base64_encode(digest, strlen((char *)digest));
return signature;
}
As you can see it's pretty short. I used OpenSSL library for hashing and some third-part base64 encoding method. Obviously, you can use any other solution, however I would recomend to test result of your code with this snippet in Python:
import hmac
import hashlib
import base64
message = b'put your request here'
dig = hmac.new(b'put your secret key here', msg=message, digestmod=hashlib.sha256).digest()
print base64.b64encode(dig).decode() # py3k-mode
Some additional notes: don't forget to put your association tag, version, correct timestamp and at least one keyword tag into request to perform actual search. This service is really helpfull in this, try it out: Signer Helper
链接地址: http://www.djcxy.com/p/39012.html