java - 用于基于浏览器的帖子的 Java AWS4 签名

标签 java amazon-web-services amazon-s3

我正在按照上面的示例使用 Java 后端创建“Base64 编码策略字符串”和“签名值”:http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

但我的“签名值”与示例不匹配。 我错过了什么吗?

我相信 getSignatureKeyHmacSHA256 没问题,因为我在可信来源中找到了。也许 getStringToSign 不正确。

这是我的代码:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64; 
import static com.google.common.io.BaseEncoding.base16; 

public class AwsSignatureGenerator {

    public static void main(String[] args) throws Exception {
        String signature = getSignature(getSignatureKey("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
                                                        "20151229", 
                                                        "us-east-1", 
                                                        "s3"));
        System.out.println(signature);
    }

    public static String getStringToSign(){
        String s3Policy = "{ \"expiration\": \"2015-12-30T12:00:00.000Z\", \"conditions\": [ {\"bucket\": \"sigv4examplebucket\"}, [\"starts-with\", \"$key\", \"user/user1/\"], {\"acl\": \"public-read\"}, {\"success_action_redirect\": \"http://sigv4examplebucket.s3.amazonaws.com/successful_upload.html\"}, [\"starts-with\", \"$Content-Type\", \"image/\"], {\"x-amz-meta-uuid\": \"14365123651274\"}, {\"x-amz-server-side-encryption\": \"AES256\"}, [\"starts-with\", \"$x-amz-meta-tag\", \"\"], {\"x-amz-credential\": \"AKIAIOSFODNN7EXAMPLE/20151229/us-east-1/s3/aws4_request\"}, {\"x-amz-algorithm\": \"AWS4-HMAC-SHA256\"}, {\"x-amz-date\": \"20151229T000000Z\" } ] }";
        return new Base64().encodeAsString(s3Policy.getBytes());
    }

    public 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"));
    }

    public 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;
    }

    public static String getSignature(byte[] key) throws Exception{
        return base16().lowerCase().encode(HmacSHA256(getStringToSign(), key));
    }
}

最佳答案

我检查了你的政策 在 base64 中它看起来像这样:

eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLCAiY29uZGl0aW9ucyI6IFsgeyJidWNrZXQiOiAic2lndjRleGFtcGxlYnVja2V0In0sIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJ1c2VyL3VzZXIxLyJdLCB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LCB7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjogImh0dHA6Ly9zaWd2NGV4YW1wbGVidWNrZXQuczMuYW1hem9uYXdzLmNvbS9zdWNjZXNzZnVsX3VwbG9hZC5odG1sIn0sIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS8iXSwgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwgeyJ4LWFtei1zZXJ2ZXItc2lkZS1lbmNyeXB0aW9uIjogIkFFUzI1NiJ9LCBbInN0YXJ0cy13aXRoIiwgIiR4LWFtei1tZXRhLXRhZyIsICIiXSwgeyJ4LWFtei1jcmVkZW50aWFsIjogIkFLSUFJT1NGT0ROTjdFWEFNUExFLzIwMTUxMjI5L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QifSwgeyJ4LWFtei1hbGdvcml0aG0iOiAiQVdTNC1ITUFDLVNIQTI1NiJ9LCB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfSBdIH0=

在 JSON 中,它看起来像这样:

{
    "expiration": "2015-12-30T12:00:00.000Z",
    "conditions": [
        {
            "bucket": "sigv4examplebucket"
        },
        [
            "starts-with",
            "$key",
            "user/user1/"
        ],
        {
            "acl": "public-read"
        },
        {
            "success_action_redirect": "http://sigv4examplebucket.s3.amazonaws.com/successful_upload.html"
        },
        [
            "starts-with",
            "$Content-Type",
            "image/"
        ],
        {
            "x-amz-meta-uuid": "14365123651274"
        },
        {
            "x-amz-server-side-encryption": "AES256"
        },
        [
            "starts-with",
            "$x-amz-meta-tag",
            ""
        ],
        {
            "x-amz-credential": "AKIAIOSFODNN7EXAMPLE/20151229/us-east-1/s3/aws4_request"
        },
        {
            "x-amz-algorithm": "AWS4-HMAC-SHA256"
        },
        {
            "x-amz-date": "20151229T000000Z"
        }
    ]
}

根据您的 JSON 和 key ,正确的签名应该是:

eb9df8c47e9c4bd6090809ed799f0146c71a10f7707aa1acc2c13e736d41ed54

根据我创建的这个应用程序 -> http://ttwd80.github.io/s3postcalculatorverify/

不过我会跳过 x-amz-date 和 x-amz-meta-uuid

另请注意,"file"字段必须是表单中的最后一个输入(提交按钮除外)。

关于java - 用于基于浏览器的帖子的 Java AWS4 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36647955/

相关文章:

java - Swing 中的增量图形

java - 使用可比排序 (Java)

mysql - Amazon RDS MySQL 和主-主复制

amazon-web-services - 添加到策略时对象无效

java - Android BluetoothSocket - 超时

java - Jenkins插件开发——环境变量

amazon-web-services - 对 Google Cloud Vision、Microsoft Azure 计算机视觉 API 或 Amazon Text Extract 进行微调

node.js - 使用强大的和(knox 或 aws-sdk)将文件上传到 Node.js 上的 S3

java - 将 Web 应用程序部署到 Amazon elastic beanstalk 时出错

ios - 为什么不支持在 iOS 上执行分段上传到 S3?