【发布时间】:2018-03-03 07:56:59
【问题描述】:
我目前有一个工作实现如下:
UI 选择一个文件 => 点击上传 => 调用我的后端 API 来请求签名,因为我不想公开我的访问权限 + 密钥 => 返回签名 + 策略 => 上传到 s3。
这适用于 v2。
String base64Policy = (new BASE64Encoder()).encode(policy.toString().getBytes("UTF-8")).replaceAll("\n", "").replaceAll("\r", "");
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1"));
String signature = (new BASE64Encoder()).encode(hmac.doFinal(base64Policy.getBytes("UTF-8"))).replaceAll("\n", "");
现在我开始有趣了,我的新存储桶位于不支持 v2 的区域。
我一直在关注 AWS 文档,但我认为我对有效负载有点误解。我真的需要让我的 UI 传入整个文件的 sha256 哈希吗?因为这似乎有点痛苦,特别是因为我的文件可能 > 1 gig。
我尝试使用的代码:
byte[] signatureKey = getSignatureKey(secretKey, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")), bucketRegion, "s3");
StringBuilder sb = new StringBuilder();
for (byte b : signatureKey) {
sb.append(String.format("%02X", b));
}
private static byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName) throws Exception {
byte[] kSecret = ("AWS4" + key).getBytes("UTF8");
byte[] kDate = HmacSHA256(dateStamp, kSecret);
byte[] kRegion = HmacSHA256(regionName, kDate);
byte[] kService = HmacSHA256(serviceName, kRegion);
byte[] kSigning = HmacSHA256("aws4_request", kService);
return kSigning;
}
private static byte[] HmacSHA256(String data, byte[] key) throws Exception {
String algorithm="HmacSHA256";
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(key, algorithm));
return mac.doFinal(data.getBytes("UTF8"));
}
但是当我尝试使用我的其余代码时,这会给出无效的签名响应。
我是不是这么难听,只是误会:https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html ?
任何帮助都将不胜感激,因为我一直在反对这种方式太久了,我不想进行太多的大修。
【问题讨论】:
-
为什么不生成一个预签名的 url 并将其传递给客户端? docs.aws.amazon.com/AmazonS3/latest/dev/…
-
POST上传的字符串签名不同。您应该签署一份 base64 编码的政策文件:docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html -
@Michael-sqlbot 我看到了,一些文档在这方面有点矛盾。 (一些示例代码)
标签: java amazon-web-services amazon-s3