服务器端加密 - 客户密钥:计算出的密钥的MD5哈希值与提供的哈希值不匹配

时间:2014-07-08 14:00:02

标签: encryption amazon-s3 amazon

我使用Jets3t作为第三方。我想用客户密钥设置服务器端加密。我正在使用以下代码,但始终收到消息"密钥的计算MD5哈希值与提供的哈希值不匹配。"

我正在使用客户密钥=" 123456"在base64编码和客户密钥-md5基于64编码(md5(客户密钥))

的x AMZ-复制源-server侧-encryption - 客户密钥 包括此标头,以便为Amazon S3提供base64编码的加密密钥,以用于解密源对象。此加密密钥必须是您在创建源对象时提供的Amazon S3;否则,Amazon S3将无法解密该对象。

的x AMZ-复制源 - 服务器端-encryption - 客户密钥-MD5
根据RFC 1321,包括此标头以提供加密密钥的base64编码的128位MD5摘要。

代码在这里

try {
    S3Copy objS3Copy = new S3Copy((S3Service)new RestS3Service(new ProviderCredentials("xxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxx") {
        @Override
        protected String getTypeName() {
        }
        @Override
        protected String getVersionPrefix() {
        }
    }), new BucketExplorerMain());
    Map<String, Object> newMetadata = new HashMap<String, Object>();
    newMetadata.put("ETag","c2fb88d3d9832648cb0b89957479c16b");
    newMetadata.put("Content-Length","1326017");
    newMetadata.put("accept","eng");
    newMetadata.put("request-id","039A1F919BAB9D1A");
    newMetadata.put("Last-Modified","Thu Feb 13 17:50:17 IST 2014");
    newMetadata.put("Date","Tue Jul 08 17:05:10 IST 2014");
    newMetadata.put("id-2","YpdNQhxKnATh6O9Pp4b/6GbDDcIcGh+UkTMQZpOyij4oNPsdOQbLGavfDSxSiuGS");
    newMetadata.put("Content-Type","text");
    newMetadata.put("x-amz-server-side-encryption-customer-algorithm","AES256");
    String sKey="123456";
    //String sEncryKey = ServiceUtils.toBase64(sKey.getBytes());
    String sEncryKey = Base64.encodeBase64String(sKey.getBytes());
    newMetadata.put("x-amz-server-side-encryption-customer-key",sEncryKey);
    try {
        //String sbased64MD5 = ServiceUtils.toBase64(ServiceUtils.computeMD5Hash(sKey.getBytes()));
         String sbased64MD5=Base64.encodeBase64String(ServiceUtils.computeMD5Hash(new ByteArrayInputStream(sKey.getBytes())));
        newMetadata.put("x-amz-server-side-encryption-customer-key-MD5",sbased64MD5);
    } catch (Exception ex) {
    }
    try {
        boolean bsuccess = objS3Copy.updateMeta("BucketName", "obj.JPG", newMetadata);
    } catch (Exception ex) {
    }

} catch (Exception ex) {
}

我的价值观是:对于密钥123456

x-amz-server-side-encryption-customer-algorithm: AES256
x-amz-server-side-encryption-customer-key: MTIzNDU2
x-amz-server-side-encryption-customer-key-MD5:  RTEwQURDMzk0OUJBNTlBQkJFNTZFMDU3RjIwRjg4M0U=
Ref: 
http://www.base64decode.org/
http://www.convertstring.com/Hash/MD5  
E10ADC3949BA59ABBE56E057F20F883E is MD5 of 123456
 The calculated MD5 hash of the key did not match the hash that was provided.

用以下行更改注释行后...我的代码工作正常。

由于

1 个答案:

答案 0 :(得分:0)

MD5输出的长度为16个字节,而Base64值RTEwQURDMzk0OUJBNTlBQkJFNTZFMDU3RjIwRjg4M0U=实际上编码为32个字节。如果您使用相同的编码打印值而不是混合hex和base64,您可以自己找到它。

我不知道ServiceUtils.computeMD5Hash()的定义在哪里,但它返回MD5哈希的大写十六进制表示而不是字节数组。

md5( "123456".getBytes() )0hE10ADC3949BA59ABBE56E057F20F883Ebase64( "E10ADC3949BA59ABBE56E057F20F883E".getBytes() )RTEwQURDMzk0OUJBNTlBQkJFNTZFMDU3RjIwRjg4M0U=,如以下代码所示:

MessageDigest md5 = MessageDigest.getInstance( "MD5" );
String keyAsText = "123456";
byte[] keyAsBytes = keyAsText.getBytes();
byte[] digestAsBytes = md5.digest( keyAsBytes );
String digestAsHex = DatatypeConverter.printHexBinary( digestAsBytes );
System.out.printf( "hex(md5(\"%s\") = %s%n", keyAsText, digestAsHex );
byte[] digestAsHexAsBytes = digestAsHex.getBytes();
String digestAsHexAsBytesAsBase64 = DatatypeConverter.printBase64Binary( digestAsHexAsBytes );
System.out.printf( "base64(\"%s\") = %s%n", digestAsHex, digestAsHexAsBytesAsBase64 );