遇到AWS4 Signature教程的麻烦,哈希与示例不匹配

时间:2019-08-28 14:39:00

标签: c# amazon-web-services .net-core aws-api-gateway

我正在研究AWS上的教程,尝试计算Authorization标头,但遇到了麻烦。 (此处的教程:https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html

我将问题缩小到任务3的最后一步。我可以按照他们的描述创建签名密钥,并获得与他们相同的结果, c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9

我可以按照他们描述的计算stringToSign并得到匹配的结果, AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/iam/aws4_request\nf536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59

但是当我尝试对字符串进行签名时,我的结果与他们的结果不符。

var kha = KeyedHashAlgorithm.Create("HMACSHA256");
kha.Key = Encoding.UTF8.GetBytes("c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9");

var sts = "AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/iam/aws4_request\nf536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59";

var signature = HexEncode(kha.ComputeHash(Encoding.UTF8.GetBytes(sts)));

运行此命令时,我的签名显示为 fe52b221b5173b501c9863cec59554224072ca34c1c827ec5fb8a257f97637b1

但是他们说应该 5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7

在任务2中,我运行HexEncode函数作为创建HashedCanonicalRequest的一部分,并且效果很好,所以我不认为它是那个函数,但是在这里以防万一:

private static string HexEncode(byte[] data, bool lowercase = true)
{
    var sb = new StringBuilder();
    for (var i = 0; i < data.Length; i++)
    {
        sb.Append(data[i].ToString(lowercase ? "x2" : "X2"));
    }
    return sb.ToString();
}

我已经尝试过使用{p>

sts

而不是使用@"AWS4-HMAC-SHA256 20150830T123600Z 20150830/us-east-1/iam/aws4_request f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59" ,但没有任何效果。我还阅读了SO上的其他一些帖子,但似乎都没有帮助。

更新: 我创建这个小提琴只是为了向自己证明这不是环境问题,但它得到的答案与我的本地代码相同。 https://dotnetfiddle.net/A5mVp9

1 个答案:

答案 0 :(得分:0)

所以事实证明,使用

kha.Key = Encoding.UTF8.GetBytes("c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9");

不正确。该字符串是十六进制编码的(因为这是本教程中要说的),但是您应该使用字节数组版本而不是十六进制编码。他们显示了十六进制编码只是为了显示目的,但是并没有说要使用常规字节数组并且不要对其进行十六进制编码!无论如何,这就是解决这个问题的方法。

如果您希望看到它的实际效果,请编写一个十六进制解码器:

public static byte[] DecodeHex(string hex)
{
    byte[] raw = new byte[hex.Length / 2];
    for (int i = 0; i < raw.Length; i++)
    {
        raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
    }
    return raw;
}

并十六进制解码我列出的字符串,并在哈希中使用该字节数组。

kha.Key = DecodeHex("c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9");