AWS S3直接上传返回无效签名(版本4签名) [英] AWS S3 direct upload returns invalid signature (version 4 signature)

查看:270
本文介绍了AWS S3直接上传返回无效签名(版本4签名)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我讨厌看到这样的答复:

I'm sick of seeing this response:

我们计算出的请求签名与您提供的签名不匹配.检查您的密钥和签名方法.

The request signature we calculated does not match the signature you provided. Check your key and signing method.

我知道此问题已在此处得到解答的版本:

I know a version this question has been answered here:

SO-使用HTTP POST的AWS S3浏览器上传给出无效的签名

我很幸运地遵循了它的每一个细节,而且我可能缺少一些简单的东西.我正在使用C#生成策略和v4 Aws签名.这是政策代码:

And I have followed every detail of it with no luck, and I'm probably missing something simple. I'm using C# to generate a policy and v4 Aws signature. Here is the policy code:

var policyBuilder = new StringBuilder();

policyBuilder.AppendFormat("{{ \"expiration\": \"{0}\",\r\n", "2017-12-30T12:00:00.000Z");
policyBuilder.Append("  \"conditions\": [\r\n");
policyBuilder.Append("    [\"starts-with\", \"$key\", \"\"],\r\n");
policyBuilder.AppendFormat("    {{\"x-amz-credential\": \"{1}\"}},\r\n",  <MyAccessKey>/20170214/us-east-2/s3/aws4_request));
policyBuilder.Append("    {\"x-amz-algorithm\": \"AWS4-HMAC-SHA256\"},\r\n");
policyBuilder.Append("    {\"x-amz-date\": \"20170214T000000Z\" }\r\n");
policyBuilder.Append("  ]\r\n}");

var policyString = policyBuilder.ToString();
var policyStringBytes = Encoding.UTF8.GetBytes(policyString);
return Convert.ToBase64String(policyStringBytes);

这是用于生成签名的代码:

This is the code used to generate the signature:

static byte[] HmacSHA256(String data, byte[] key)
{
    String algorithm = "HmacSHA256";
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(algorithm);
    kha.Key = key;

    return kha.ComputeHash(Encoding.UTF8.GetBytes(data));
}

static byte[] GetSignatureKey(String key, String dateStamp, String regionName, String serviceName)
{
    byte[] kSecret = Encoding.UTF8.GetBytes(("AWS4" + key).ToCharArray());
    byte[] kDate = HmacSHA256(dateStamp, kSecret);
    byte[] kRegion = HmacSHA256(regionName, kDate);
    byte[] kService = HmacSHA256(serviceName, kRegion);
    byte[] kSigning = HmacSHA256("aws4_request", kService);

    return kSigning;
}

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

将所有内容组合在一起的方法:

The method that brings it all together:

public string GetS3PolicySignatureV4(string policy)
{
    byte[] signingKey = GetSignatureKey(<MySecretKey>, "20170214T000000Z", "us-east-2", "s3");
    byte[] signature = HmacSHA256(policy, signingKey);
    return AWS4SignerBase.ToHexString(signature, true);
}

这是html表单:

<form action="http://<BucketName>.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="key" value="<FileKey>" />
    <input type="hidden" name="x-amz-credential" value="<MyAccessKey>/20170214/us-east-2/s3/aws4_request"/>
    <input type="hidden" name="x-amz-algorithm" value="AWS4-HMAC-SHA256" />
    <input type="hidden" name="x-amz-date" value="20170214T000000Z" />
    <input type="hidden" name="policy" value='<Base64PolicyResult>' />
    <input type="hidden" name="x-amz-signature" value="<GenerateSignature>" />
    File:
    <input type="file" name="file" /> <br />
    <input type="submit" name="submit" value="Upload to Amazon S3" />
</form>

我已经验证了本示例中示例策略的结果:

I have verified that the example policy result in this example:

AWS-示例:基于浏览器的上传使用HTTP POST(使用AWS Signature版本4)

以及生成的签名与示例匹配.但是,当我尝试POST到S3时,总是得到可怕的响应.

as well as the resulting signature matched the example using the provided parameters and keys. But when I try to POST to S3, I always get that dreaded response.

推荐答案

问题是传递给GetSignatureKey方法的日期格式不正确.应该是"20170214",隐藏的表单字段x-amz-date是ISO8601格式的"20170214T000000Z".我正在将相同的值传递给GetSignatureKey方法.

The issue was that the date passed into the GetSignatureKey method was incorrectly formatted. Should have just been "20170214" and the hidden form field x-amz-date is the ISO8601 format of "20170214T000000Z". I was passing in the same value into the GetSignatureKey method.

这篇关于AWS S3直接上传返回无效签名(版本4签名)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆