【问题标题】:SignatureDoesNotMatch when trying to PUT an object to REST API from JSP - AWS V4 signature尝试从 JSP 将对象放入 REST API 时的 SignatureDoesNotMatch - AWS V4 签名
【发布时间】:2017-01-31 10:24:33
【问题描述】:

我正在按照以下步骤使用 V4 创建 PUT 请求:http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

刚刚创建了一个用于尝试将文件上传到 S3 存储桶的 JSP。问题是我总是得到一个 403 - Forbidden。通过详细查看响应,它说是“SignatureDoesNotMatch”错误,消息是“我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。' 内容实际上只是字符串“文件内容”。这些是发送的标头:

PUT /test.txt HTTP/1.1
Accept: /
Host: my host.s3.amazonaws.com
Date: Thu, 22 Sep 2016 04:51:52 GMT
Authorization: AWS4-HMAC-SHA256 Credential=My access ID/20160922/us-east-1/s3/aws4_request,SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class,Signature=1bqb/RTdtsOP42zs7UR4d6Id6YlNgIbO86Q1m2RuGFs=
x-amz-date: 20160922T045152Z
x-amz-content-sha256: 69423BABE8E61AAB549F347BCC8B9D77B7DCACA198FB0597BDE0B5F97F968E38
x-amz-storage-class: REDUCED_REDUNDANCY
Content-Type: text/plain
Content-Length: 13

响应正文的重要部分是:

<CanonicalRequest>PUT
/test.txt

content-length:13
content-type:text/plain
date:Thu, 22 Sep 2016 04:51:52 GMT
host:my host.s3.amazonaws.com
x-amz-content-sha256:69423BABE8E61AAB549F347BCC8B9D77B7DCACA198FB0597BDE0B5F97F968E38
x-amz-date:20160922T045152Z
x-amz-storage-class:REDUCED_REDUNDANCY

content-length;content-type;date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class
69423BABE8E61AAB549F347BCC8B9D77B7DCACA198FB0597BDE0B5F97F968E38</CanonicalRequest>

<StringToSign>AWS4-HMAC-SHA256
20160922T045152Z
20160922/us-east-1/s3/aws4_request
17957a94c148833cd2f1132a8a4ffcfe6d2c83a71501a063f7a2ff9e7acfa1aa</StringToSign>

<SignatureProvided>1bqb/RTdtsOP42zs7UR4d6Id6YlNgIbO86Q1m2RuGFs</SignatureProvided>

我很确定 CanonicalRequest 和 StringToSing 在我得到的响应和我正在创建的请求上是相等的,因为我们现在正在记录所有这些信息以进行调试。通过比较,我可以确保数据完全一样,除了签名末尾的“=”字符:

授权头签名:

1bqb/RTdtsOP42zs7UR4d6Id6YlNgIbO86Q1m2RuGFs=

SignatureProvided 在响应正文中:

1bqb/RTdtsOP42zs7UR4d6Id6YlNgIbO86Q1m2RuGFs

我只是无法弄清楚为什么我会收到此 SignatureDoesNotMatch 错误,似乎一切正常(除了这个 '=' 字符,我不知道为什么响应中的 SignatureProvided 中没有包含)。我已附上用于创建请求的代码。

我有什么遗漏吗?是我第一次尝试与 AWS 集成。我已经花了很多天试图让它工作,这很烦人:(

提前感谢您的帮助!

编辑:从签名中删除最后一个“=”字符无效,结果与上述相同。

【问题讨论】:

  • 看起来在创建签名的过程中,您正在使用 URL 编码,它添加了额外的“=”。我不确定创建签名的过程。
  • 感谢您的回复拉胡尔!我正在创建一个 HmacSHA256 mac 并使用我的 AWSSecretKey 进行签名。使用 DatatypeConverter.printBase64Binary 转换回字符串,不确定 URL 编码发生在哪里

标签: java rest jsp amazon-web-services amazon-s3


【解决方案1】:

一个快速的谷歌搜索告诉我,额外的“=”实际上是由一个填充因子添加的,甚至更快的测试用例帮助我找到了一种没有填充的编码方法。

@Test
public void testSign(){
    byte[] b = Base64.getDecoder().decode("1bqb/RTdtsOP42zs7UR4d6Id6YlNgIbO86Q1m2RuGFs=");
    System.out.println(Base64.getEncoder().withoutPadding().encodeToString(b));
}

不出所料,如果我删除 withoutPadding(),最后我得到 =,也许你可以使用 java.net.Base64 进行无填充编码。

【讨论】:

  • 刚刚注意到 Amazon SDK 中的自定义 base64 编码...不是传统方式(不是任何本机 java 库):github.com/aws/aws-sdk-java/blob/… 现在将使用他们的 SDK,稍后再继续这项工作,我有已经为此浪费了太多时间。再次感谢拉胡尔!
猜你喜欢
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2020-06-24
  • 2015-12-22
  • 2015-09-05
相关资源
最近更新 更多