首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AWS S3直接上传返回无效签名(版本4签名)

AWS S3直接上传返回无效签名(版本4签名)
EN

Stack Overflow用户
提问于 2017-02-14 22:43:56
回答 1查看 1.7K关注 0票数 3

我受够了这种反应:

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

我知道有一个版本这个问题已经在这里得到了回答:

使用HTTP上传的AWS S3浏览器提供了无效的签名

我对它的每一个细节都一丝不苟,我可能错过了一些简单的东西。我使用C#生成策略和v4 Aws签名。以下是策略代码:

代码语言:javascript
复制
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);

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

代码语言:javascript
复制
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();
}

把这一切结合在一起的方法:

代码语言:javascript
复制
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表单:

代码语言:javascript
复制
<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>

在这个示例中,我已经验证了示例策略的结果:

AWS -示例:使用HTTP的基于浏览器的上载(使用AWS签名版本4)

以及使用提供的参数和密钥匹配示例的结果签名。但当我试图在S3上发帖时,我总是会得到令人恐惧的回应。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-15 13:35:06

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42237602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档