C# 上载带有MD5哈希的流会导致;您指定的Content-MD5无效";

C# 上载带有MD5哈希的流会导致;您指定的Content-MD5无效";,c#,hash,amazon-web-services,amazon-s3,md5,C#,Hash,Amazon Web Services,Amazon S3,Md5,我正在使用amazons3开发一个实现。我使用亚马逊C#SDK,并尝试使用putObject方法上传创建的ZIP文件 当我上传文件时,出现以下错误: {Amazon.S3.AmazonS3Exception: The Content-MD5 you specified was invalid 我生成了一个很好的内存流,我可以将它毫无错误地上传到AmazonS3。但是,当我提供以下行时,它会给我带来问题: request.MD5Digest = md5; 我是否以正确的方式证明MD5?我的MD

我正在使用
amazons3
开发一个实现。我使用亚马逊C#SDK,并尝试使用putObject方法上传创建的ZIP文件

当我上传文件时,出现以下错误:

{Amazon.S3.AmazonS3Exception: The Content-MD5 you specified was invalid
我生成了一个很好的内存流,我可以将它毫无错误地上传到AmazonS3。但是,当我提供以下行时,它会给我带来问题:

request.MD5Digest = md5;
我是否以正确的方式证明MD5?我的MD5代正确吗?还是有其他问题

对我的上传代码的要求

Once the Zip file has been created and you have calculated an MD5 sum value of that file, you should 
transfer the file to the AWS S3 bucket identified in the S3Access XML. 
Transfer the file using the AmazonS3, PutObjectRequest and TransferManagerclasses. 
Ensure the following meta data attributes are included via adding an ObjectMetaDataclass instance to the
PutObjectRequest:
• MD5Sum (via setContentMD5)
• Mime ContentType (setContentType)
我的上传代码

client.PutObject()给出了错误:

public void UploadFile(string bucketName, Stream uploadFileStream, string remoteFileName, string md5)
        {
            using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKeyID, secretAccessKeyID, config))
            {
                try
                {
                    StringBuilder stringResp = new StringBuilder();

                    PutObjectRequest request = new PutObjectRequest();
                   // request.MD5Digest = md5;
                    request.BucketName = bucketName;
                    request.InputStream = uploadFileStream;
                    request.Key = remoteFileName;
                    request.MD5Digest = md5;

                    using (S3Response response = client.PutObject(request))
                    {
                        WebHeaderCollection headers = response.Headers;
                        foreach (string key in headers.Keys)
                        {
                            stringResp.AppendLine(string.Format("Key: {0}, value: {1}", key,headers.Get(key).ToString()));
                            //log headers ("Response Header: {0}, Value: {1}", key, headers.Get(key));
                        }
                    }
                }
                catch (AmazonS3Exception amazonS3Exception)
                {
                    if (amazonS3Exception.ErrorCode != null && (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") || amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
                    {
                        //log exception - ("Please check the provided AWS Credentials.");
                    }
                    else
                    {
                        //log exception -("An error occurred with the message '{0}' when writing an object", amazonS3Exception.Message);
                    }
                }
            }
        }
总体方法

我的流程方法(查看总体流程)。很抱歉,代码的当前状态是伪代码,而不是生产代码:

 public void Process(List<Order> order)
    {
        var zipName = UserName + "-" + DateTime.Now.ToString("yy-MM-dd-hhmmss") + ".zip";
        var zipPath = HttpContext.Current.Server.MapPath("~/Content/zip-fulfillment/" + zipName);

        CreateZip(order, zipPath);


        var s3 = GetS3Access();

        var amazonService = new AmazonS3Service(s3.keyid, s3.secretkey, "s3.amazonaws.com");
        var fileStream = new MemoryStream(HelperMethods.GetBytes(zipPath));
        var md5val = HelperMethods.GetMD5HashFromStream(fileStream);
        fileStream.Position = 0;
        amazonService.UploadFile(s3.bucket, fileStream, zipName, md5val);

        var sqsDoc = DeliveryXml(md5val, s3.bucket, "Test job");

        amazonService.SendSQSMessage(sqsDoc.ToString(), s3.postqueue);
    }
公共作废流程(列表顺序)
{
var zipName=UserName+“-”+DateTime.Now.ToString(“yy-MM-dd-hhmmss”)+“.zip”;
var zipPath=HttpContext.Current.Server.MapPath(“~/Content/zip fulfillment/”+zipName);
CreateZip(订单,zipPath);
var s3=GetS3Access();
var amazonService=newamazons3service(s3.keyid,s3.secretkey,“s3.amazonaws.com”);
var fileStream=newmemoryStream(HelperMethods.GetBytes(zipPath));
var md5val=HelperMethods.GetMD5HashFromStream(fileStream);
fileStream.Position=0;
上传文件(s3.bucket、fileStream、zipName、md5val);
var sqsDoc=DeliveryXml(md5val,s3.bucket,“测试作业”);
amazonService.SendSQSMessage(sqsDoc.ToString(),s3.postqueue);
}
MD5哈希方法:

此方法用于从my memorystream创建MD5哈希:

    public static string GetMD5HashFromStream(Stream stream)
    {

        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] retVal = md5.ComputeHash(stream);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < retVal.Length; i++)
        {
            sb.Append(retVal[i].ToString("x2"));
        }
        return sb.ToString();
    }
公共静态字符串GetMD5HashFromStream(Stream)
{
MD5 MD5=新的MD5CryptoServiceProvider();
字节[]retVal=md5.ComputeHash(流);
StringBuilder sb=新的StringBuilder();
for(int i=0;i
编辑

Once the Zip file has been created and you have calculated an MD5 sum value of that file, you should 
transfer the file to the AWS S3 bucket identified in the S3Access XML. 
Transfer the file using the AmazonS3, PutObjectRequest and TransferManagerclasses. 
Ensure the following meta data attributes are included via adding an ObjectMetaDataclass instance to the
PutObjectRequest:
• MD5Sum (via setContentMD5)
• Mime ContentType (setContentType)

刚刚在总体方法中添加了fileStream.Position=0。但是仍然是完全相同的问题。

我怀疑问题可能是,在计算流的散列之后,流留在数据的末尾。。。因此,当其他任何内容稍后从中读取时,将不会有数据。在调用
GetMD5HashFromStream

fileStream.Position = 0;
这将“倒带”流,以便您可以再次读取

编辑:只是看了一下文档,尽管上面的问题是存在的,但它不是唯一的问题。目前,您正在附加MD5哈希的十六进制表示形式-但是状态:

Content-MD5:消息的base64编码的128位MD5摘要

请注意“base64编码”部分。因此,您需要将MD5代码更改为:

public static string GetMD5HashFromStream(Stream stream)
{
    using (MD5 md5 = MD5.Create())
    {
        byte[] hash = md5.ComputeHash(stream);
        return Convert.ToBase64String(hash);
    }
}

如果您使用的是AWS.NETSDK,那么实际上您可以使用他们自己的实用程序类来实现这一点。看看这个测试,搜索“MD5Digest”,你会看到类似的东西

var putObjectRequest = new PutObjectRequest()
{
    BucketName = bucketName,
    Key = key,
    ContentBody = content,
    MD5Digest = AmazonS3Util.GenerateChecksumForContent(content, true),
};

if (retainUntilDate.HasValue)
{
    putObjectRequest.ObjectLockMode = ObjectLockMode.Governance;
    putObjectRequest.ObjectLockRetainUntilDate = retainUntilDate.Value;
}

我只是试了一下,但没有解决问题。嗯,不过非常感谢你的建议-那也会是个问题是的!非常感谢(再次)。。。真的很有帮助:)Thnx