用Java签署Amazon S3策略

mck*_*mey 7 java sha1 amazon-s3 hmac

出于某种原因,我正在努力使用我的Amazon S3上传策略的签名生成.我发誓,我有一点工作,但不再.任何帮助将非常感激.我需要一双新鲜的眼睛.

Amazon S3 Signature Tester的输出进行比较时,我没有得到相同的签名.但是,当我直接使用该工具发出的签名时,一切正常.所以问题肯定在我的签署过程中.此外,该工具中出现的"要签名的字符串"十六进制解码与我签名的输入策略相同.

AWS文档说构建策略签名的过程应该是这样的:

  1. 使用UTF-8编码策略.
  2. 使用Base64对这些UTF-8字节进行编码.
  3. 使用HMAC SHA-1使用您的秘密访问密钥签署策略.
  4. 使用Base64对SHA-1签名进行编码.

似乎足够直截了当.模棱两可的唯一地方可能是#3.AWS文档显示了用于生成HMAC-SHA1的示例代码段,这与我见过的其他Java加密示例一致.

我正在使用Apache Commons的Base64的v1.6.我的签名代码基本上如下所示:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

/* ... */

private static final String UTF8 = "UTF-8";
private static final String HMACSHA1 = "HmacSHA1";

public static String sign(String secret, String data) {
    byte[] dataBytes = data.getBytes(UTF8);
    byte[] secretBytes = secret.getBytes(UTF8);

    SecretKeySpec signingKey = new SecretKeySpec(secretBytes, HMACSHA1);

    Mac mac = Mac.getInstance(HMACSHA1);
    mac.init(signingKey);
    byte[] signature = mac.doFinal(dataBytes);

    return Base64.encodeBase64String(signature);
}
Run Code Online (Sandbox Code Playgroud)

然后我对这个签名的使用看起来像:

String signature = sign(
    /* AWS Secret Access Key copied directly out of the AWS Console */,
    /* policy properly serialized as JSON */);
Run Code Online (Sandbox Code Playgroud)

mck*_*mey 5

好的,我找到了.显然今天我已经有效地跳过了第二步.我确实将策略JSON编码为Base64,但后来我直接签署了JSON字符串而不是Base64字符串.

步骤#3应该改写为" 使用HMAC SHA-1使用您的秘密访问密钥签署Base64策略".

我想我会留下这个以防其他人遇到类似的问题.