Amazon web services AmazonS3对象签名后计算示例

Amazon web services AmazonS3对象签名后计算示例,amazon-web-services,amazon-s3,Amazon Web Services,Amazon S3,我在Amazon上工作,使用的代码几乎是直接从中复制的。我派生的签名与示例中列出的签名不匹配。使用它们的常规值,我将获得所有中间键的匹配值。帖子上的签名是正确的还是我遗漏了一些明显的东西 // https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-java private static byte[] HmacSHA256(String data, byte[]

我在Amazon上工作,使用的代码几乎是直接从中复制的。我派生的签名与示例中列出的签名不匹配。使用它们的常规值,我将获得所有中间键的匹配值。帖子上的签名是正确的还是我遗漏了一些明显的东西

// https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-java
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"));
}

private static void printtHex(String msg, byte[] buffer) {
    String hex = DatatypeConverter.printHexBinary(buffer).toLowerCase();
    System.out.format("%s: %s%n", msg, hex);
}

// https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-java
private static byte[] getSignatureKey(String key, String dateStamp, String regionName,
                                      String serviceName, boolean debugIt)
        throws Exception {
    byte[] kSecret = ("AWS4" + key).getBytes("UTF8");
    if (debugIt)
        printtHex("kSecret", kSecret);
    byte[] kDate = HmacSHA256(dateStamp, kSecret);
    if (debugIt)
        printtHex("kDate", kDate);
    byte[] kRegion = HmacSHA256(regionName, kDate);
    if (debugIt)
        printtHex("kRegion", kRegion);
    byte[] kService = HmacSHA256(serviceName, kRegion);
    if (debugIt)
        printtHex("kService", kService);
    byte[] kSigning = HmacSHA256("aws4_request", kService);
    if (debugIt)
        printtHex("kSigning", kSigning);
    return kSigning;
}

public static void test() {
    try {
        // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html
        // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
        String expectedBase64Policy = "eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9";
        String expectedSignature = "46503978d3596de22955b4b18d6dfb1d54e8c5958727d5bdcd02cc1119c60fc9";
        String secretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";

        byte[] signingKey = getSignatureKey(secretKey, "20151229", "us-east-1", "s3", false);
        byte[] signedPolicy = HmacSHA256(expectedBase64Policy, signingKey);
        String calculatedSignature = DatatypeConverter.printHexBinary(signedPolicy)
                .toLowerCase();

        System.out.println("Generating signature for policy string for POST object");
        System.out.println("EXP: " + expectedSignature);
        System.out.println("GOT: " + calculatedSignature);

        // Test example from
        // https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-other
        // intermediate keys match expected
        System.out.println("Generating signing for test example");
        getSignatureKey("wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", "20120215", "us-east-1",
                        "iam", true);

    } catch (Exception e) {
        e.printStackTrace();
    }
}
我得到的输出:

Generating signature for policy string for POST object
EXP: 46503978d3596de22955b4b18d6dfb1d54e8c5958727d5bdcd02cc1119c60fc9
GOT: 8afdbf4008c03f22c2cd3cdb72e4afbb1f6a588f3255ac628749a66d7f09699e
Generating signing for test example
kSecret: 41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559
kDate: 969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d
kRegion: 69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c
kService: f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa
kSigning: f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d

我没有对此进行进一步的研究,但是关于
8afdbf…
Wow,有一些熟悉的东西。是的,我应该用谷歌搜索我得到的签名。看起来似乎有很多人都在为同一个问题苦苦挣扎,并得出了相同的结果。我假设这是一个文档错误,除非有人能证明它是错的。除了你提供的链接之外,还有其他一些例子:是的,这真的很奇怪。我怀疑有一种解释可以支持,可能与策略文档编码有关——您的策略base64是否与示例完全一致?一个杂散的
\r
\n
可能会把它甩掉。对于任何给定的策略,只有一个正确的签名,但这仅适用于策略的base64(json())。由于策略是一个序列化格式的字符串,该字符串允许空白,但后来被base64视为字节,因此策略可能有不同的base64和不同的签名,我想可能也是这样,所以我对示例中提供的base64策略字符串进行了签名,这就是8afdbf。。。签名。