从GCS下载对象时如何检查MD5

时间:2018-01-15 18:31:47

标签: c# google-cloud-storage md5

我想从GCS下载文件时进行MD5检查。然而,似乎我没有得到正确的MD5 ......一个例子:

local 1B2M2Y8AsgTpgAmY7PhCfg==, cloud JWSLJAR+M3krp1RiOAJzOw==

但我很确定文件没有损坏......

以下代码使用C#7.0,使用System.Security.Cryptography;

           using (var memStream = new MemoryStream())
            {
                _StorageClient.DownloadObject(bucketName, gcsObj.Name, memStream);
                try
                {
                    using (var md5 = MD5.Create())
                    {
                        var hash = md5.ComputeHash(memStream);
                        localMd5 = Convert.ToBase64String(hash);
                    }
                    Console.WriteLine($"local {localMd5}, cloud {gcsObj.Md5Hash}");
                }
                catch
                {
                    Console.WriteLine("Error getting md5 checksum");
                }
            }

另一个问题是: 文件的c# lib that I tried to get the CRC32C value仅返回uint类型,但GCS对象的Crc32C值是一个字符串。如何比较它们?

2 个答案:

答案 0 :(得分:1)

从您的示例中,我假设您的示例哈希来自x-goog-hash标题?

如果是这种情况,您可以检查同一文件的值x-goog-stored-content-encoding是多少?如果是gzip,则将压缩副本上载到GCS,并以gzip格式存储。在这种情况下,x-goog-hash是存储在GCS上的 gzipped副本 的MD5。

要验证它,你必须下载压缩版本(不确定你使用的C#库是否可以),并检查它的MD5哈希值。

对于CRC32C,您可以使用:

Convert.ToBase64String(BitConverter.GetBytes(crc32c))

但同样适用:如果它是gziped,这是gzip版本的CRC32C。

要检查对象元数据,您可以使用:

gsutil stat gs://some-bucket/some-object

示例输出:

Creation time:          Sat, 20 Jan 2018 11:09:11 GMT
Update time:            Sat, 20 Jan 2018 11:09:11 GMT
Storage class:          MULTI_REGIONAL
Content-Encoding:       gzip
Content-Length:         5804
Content-Type:           application/msword
Hash (crc32c):          kxvpkw==
Hash (md5):             bfH75gryTXKgNosp1Smxvw==
ETag:                   CO7sotCz5tgCEAE=
Generation:             1516446551684718
Metageneration:         1

此对象以gzip格式存储。 MD5 / CRC32C都不会与解压缩副本匹配。

答案 1 :(得分:-1)

您不应使用Convert.ToBase64String方法。

请改为尝试:

static string Md5HashToString(byte[] hash)
{
    // Create a new StringBuilder to collect the bytes
    // and create a string.
    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of the hashed data 
    // and format each one as a hexadecimal string.
    for (int i = 0; i < hash.Length; i++)
    {
        sBuilder.Append(hash[i].ToString("x2"));
    }

    // Return the hexadecimal string.
    return sBuilder.ToString();
}