为什么我的签名与亚马逊的例子有所不同? (C ++ / REST /授权签名版本4)

时间:2014-10-01 12:52:03

标签: c++ rest amazon-web-services authorization digital-signature

我正在关注this page上给出的示例,并且最终使用here给出的详细信息获得了正确的签名。

我的问题是我正确地获得了签名ced6826de92d2bdeed8f846f0bf508e8559e98e4b0199114b84c54174deb456c但是,只要我使用相同的方法并更改this page上的GET示例的变量,它就会给我签名c2eb7ddb12cb2c46489fdf97947e68b24c3716而不是f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41

这是使用openSSL进行HMAC和SHA256散列的C ++代码。

  

测试功能



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), &region), &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功能



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




  

十六进制函数



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

2 个答案:

答案 0 :(得分:4)

HMAC函数导致了这个问题,我正在将unsigned char *转换为char *并获取该长度,该长度一旦达到零就会结束,从而给出不同的长度。更改了函数以包含键和值的长度。

HMAC长度从64更改为32,并将32传递给密钥长度的函数。

要警告其他人在亚马逊网站上提供的示例,请注意,签署日期的字符串不是ISO格式,它与您在日期标题中传递的日期和时间相同,即10月6日星期一等... < / p>

答案 1 :(得分:0)

如果您使用的是C ++ 11,我们也可以使用vector。使用vector的优点是你不必跟踪内存释放。

我在这里有一个相同的实现 - HMAC SHA256 in C++ (DynamoDB)