gpt4 book ai didi

c# - 在 C# 中为 AWS REST 查询创建 HMAC 签名

转载 作者:行者123 更新时间:2023-11-30 12:26:23 27 4
gpt4 key购买 nike

因此,我正在尝试对 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。

EDIT2: 经过长时间的尝试,我终于发现 AWS 需要 Signature= 而不是 signature=,但现在我得到了一个SignatureDoesNotMatch 错误,所以接下来我需要解决这个问题。我也不知道为什么这种问题会被否决。一旦我弄清楚了语法,在任何应用程序中调用 AWS API 都是微不足道的。如果您使用 AWS .NET SDK,您将向二进制文件添加 6 兆字节。这怎么能不值得呢?

解决方案:

这段代码可以工作,并且会在没有 AWS SDK 的情况下发送 SNS 通知:

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

最佳答案

推出自己的解决方案而不是使用 SDK 并没有错。事实上,我更喜欢它,因为除了更轻量级的代码之外,你更有可能理解意外行为的问题,因为你正在使用 native 界面。

这是你所缺少的:

Add the query string parameters ... sorted using lexicographic byte ordering

http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html

例如,TargetArn 不应在 SignatureMethod 之前。它们需要排序。对于任何给定的消息,只有一个可能的正确签名,因此排序顺序至关重要。

关于c# - 在 C# 中为 AWS REST 查询创建 HMAC 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28966075/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com