我正在尝试对AWS的SNS服务进行REST API调用,但是一直收到"IncompleteSignature"错误。我参考了http://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/#csharp关于如何创建签名的内容和http://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/HMACAuth.html中的信息来确定签名内容。
以下是我编写的测试代码:
以下是我编写的测试代码:
static void Main(string[] args)
{
string region = "us-west-2";
string msg = "This is a test!";
string secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
string key = "XXXXXXXXXXXXXXX";
string arn = "arn:aws:sns:us-west-2:xxxxxxxxxx:snstest1";
string query = "Action=Publish&Message=" + HttpUtility.UrlEncode(msg) + "&MessageStructure=json&TargetArn=" + HttpUtility.UrlEncode(arn) + "&SignatureMethod=HmacSHA256&AWSAccessKeyId=" + key + "&SignatureVersion=2&Timestamp=" + HttpUtility.UrlEncode(DateTime.UtcNow.ToString("o"));
string tosign = "GET\nsns." + region + ".amazonaws.com\n/\n" + query;
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(tosign);
var hmacsha256 = new HMACSHA256(keyByte);
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
query += "&signature=" + HttpUtility.UrlEncode(Convert.ToBase64String(hashmessage));
Console.WriteLine("REST Call: https://sns." + region + ".amazonaws.com/?" + query);
}
你有什么想法可能出了问题吗?
编辑:我尝试使用http://wiki.alphasoftware.com/~alphafiv/DotNet+Example%3A+Digital+Hash中的代码更改签名部分,它使用CharArray而不是byte[],不确定哪个是正确的,它会产生不同的签名,但仍无法与AWS一起使用。
编辑2:经过长时间的尝试,我终于发现AWS希望使用Signature =
而不是signature =
,但现在我收到一个SignatureDoesNotMatch错误,所以我需要接下来解决这个问题。此外,我不知道为什么这种类型的问题会被downvote。一旦我弄清楚语法,AWS API调用将在任何应用程序中都很容易完成。如果您使用AWS .NET SDK,则会向二进制文件添加6兆字节。这不是一个值得追求的事情吗?
解决方案:
此代码有效,并且将发送SNS通知而无需使用AWS SDK:
static void Main(string[] args)
{
string region = "us-west-2";
string msg = "Test test: sfdfds\nfsd: sdsda\n";
string secret = "XXXXXXXXXXXXXXXXXXX";
string key = "ZZZZZZZZZZZ";
string arn = "arn:aws:sns:us-west-2:YYYYYYYYYYY:snstest1";
string query = "AWSAccessKeyId=" + Uri.EscapeDataString(key) + "&Action=Publish&Message=" + Uri.EscapeDataString(msg) + "&SignatureMethod=HmacSHA256&SignatureVersion=2&TargetArn=" + Uri.EscapeDataString(arn) + "&Timestamp=" + Uri.EscapeDataString(System.DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"));
string tosign = "GET\nsns." + region + ".amazonaws.com\n/\n" + query;
Console.WriteLine(tosign + "\n");
UTF8Encoding encoding = new UTF8Encoding();
HMACSHA256 hmac = new HMACSHA256(encoding.GetBytes(secret));
string signature = Convert.ToBase64String(hmac.ComputeHash(encoding.GetBytes(tosign)));
query += "&Signature=" + Uri.EscapeDataString(signature);
Console.WriteLine("REST Call: https://sns." + region + ".amazonaws.com/?" + query);
}