我使用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.
用以下行更改注释行后...我的代码工作正常。
由于
答案 0 :(得分:0)
MD5输出的长度为16个字节,而Base64值RTEwQURDMzk0OUJBNTlBQkJFNTZFMDU3RjIwRjg4M0U=
实际上编码为32个字节。如果您使用相同的编码打印值而不是混合hex和base64,您可以自己找到它。
我不知道ServiceUtils.computeMD5Hash()
的定义在哪里,但它返回MD5哈希的大写十六进制表示而不是字节数组。
md5( "123456".getBytes() )
为0hE10ADC3949BA59ABBE56E057F20F883E
,base64( "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 );