在Haxe中为AWS S3 REST生成Content-MD5

在Haxe中为AWS S3 REST生成Content-MD5,rest,amazon-web-services,amazon-s3,haxe,Rest,Amazon Web Services,Amazon S3,Haxe,我正试图在Haxe(编译到PHP)中对AWSS3的REST调用中添加Content-MD5头。它是由 var contentMD5 = haxe.crypto.Base64.encode(haxe.io.Bytes.ofString(haxe.crypto.Md5.encode(_data))); 在我的示例中,数据是 <Delete><Object><Key>nathan/storage/72ENgrtnpA5VAoy7zEpzPRNEChN0TRGc&l

我正试图在Haxe(编译到PHP)中对AWSS3的REST调用中添加Content-MD5头。它是由

var contentMD5 = haxe.crypto.Base64.encode(haxe.io.Bytes.ofString(haxe.crypto.Md5.encode(_data)));
在我的示例中,数据是

<Delete><Object><Key>nathan/storage/72ENgrtnpA5VAoy7zEpzPRNEChN0TRGc</Key></Object><Object><Key>nathan/storage/7rlZZSJFvZ7AxUhQZsh4ufn9M2x8m1ae</Key></Object><Object><Key>nathan/storage/HN8NFlUnJiiGo7qlddvRrlGE6hPmWMnZ</Key></Object><Object><Key>nathan/storage/SFsZ8z63DswEVFJQJqmUwbenaWyfZ8zb</Key></Object><Object><Key>nathan/storage/YSYXXgYbSZixOKo27PL65ii6nCeiFesl</Key></Object></Delete>
在我看来,生成的MD5是正确的。我用其他工具验证了这个值。另外,请注意,
x-amz-content-sha256
基于相同的
\u数据
,AWS在我以前的(非删除)调用中接受了该标题

我错过了什么?为什么我的MD5值与AWS生成的值不同?

您非常接近

问题是:

md5哈希在二进制表示中是16个字节,在十六进制表示中是32个字符,在base64中是24个字符(包括填充)

你的大约是你的两倍长。您似乎采用了32个字符的十六进制md5和base64编码,从而生成了一个大约44个字符的base64字符串,而不仅仅是二进制形式的编码

请注意,尽管我断言您编码的是32个初始字节,而不是16个,但输出的长度44 vs 24不是2的因子。这是意料之中的,因为base64输出字节=ceil(输入字节/3)*4

我的专业知识是S3API,而不是我从未使用过的haxe,因此上面的内容几乎可以肯定是正确的,但下面是一些猜测

var contentMD5 = haxe.crypto.Base64.encode(haxe.crypto.Md5.make(_data));

任何想在java中实现这一点的人都可以使用这段代码

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Base64;
public class GenerateMD5 {
public static void main(String args[]) throws Exception{
    String s = "<CORSConfiguration> <CORSRule> <AllowedOrigin>http://www.example.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> </CORSConfiguration>";

        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(s.getBytes());
        byte[] digest = md.digest();
        StringBuffer sb = new StringBuffer();
        /*for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }*/
        System.out.println(sb.toString());
        StringBuffer sbi = new StringBuffer();
        byte [] bytes = Base64.encodeBase64(digest);
        String finalString = new String(bytes);
        System.out.println(finalString);
    }
}
import java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
导入org.apache.commons.codec.binary.Base64;
公共类生成器D5{
公共静态void main(字符串args[])引发异常{
字符串s=”http://www.example.com 将帖子删除*3000*获取*3000”;
MessageDigest md=MessageDigest.getInstance(“MD5”);
md.update(s.getBytes());
字节[]摘要=md.digest();
StringBuffer sb=新的StringBuffer();
/*for(字节b:摘要){
sb.append(字符串格式(“%02x”,b&0xff));
}*/
System.out.println(sb.toString());
StringBuffer sbi=新的StringBuffer();
byte[]bytes=Base64.encodeBase64(摘要);
字符串finalString=新字符串(字节);
系统输出打印LN(最终打印);
}
}

注释代码是大多数人错误的地方,将其更改为十六进制

非常感谢Michael,非常全面。您建议的Haxe代码不起作用,但它让我找到了正确的解决方案:
var contentMD5=Haxe.crypto.Base64.encode(Haxe.crypto.Md5.make(Haxe.io.Bytes.ofString(_data))
var contentMD5 = haxe.crypto.Base64.encode(haxe.crypto.Md5.make(_data));
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Base64;
public class GenerateMD5 {
public static void main(String args[]) throws Exception{
    String s = "<CORSConfiguration> <CORSRule> <AllowedOrigin>http://www.example.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> </CORSConfiguration>";

        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(s.getBytes());
        byte[] digest = md.digest();
        StringBuffer sb = new StringBuffer();
        /*for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }*/
        System.out.println(sb.toString());
        StringBuffer sbi = new StringBuffer();
        byte [] bytes = Base64.encodeBase64(digest);
        String finalString = new String(bytes);
        System.out.println(finalString);
    }
}