【问题标题】:SHA-1 Hash a byte array vs a file streamSHA-1 散列字节数组与文件流
【发布时间】:2017-05-04 19:12:28
【问题描述】:

我正在编写一个允许用户上传文件(图像、视频等)的 API。我使用 SHA-1 哈希来确保不会多次上传同一个文件。以前我们只允许较小的文件,所以我将它们读入字节数组并对其进行哈希处理,但现在我们允许更大的文件,所以我使用文件流。问题是 SHA-1 算法返回不同的哈希值。我需要弄清楚如何获得相同的哈希,而不管方法如何,即使我必须将字节数组转换为文件流或其他东西。但是,我尝试将字节数组写入临时文件并读取它,它返回与字节数组相同的哈希值。这是一个示例控制台应用程序,它显示了我在做什么:

static void Main(string[] args)
{
    string file = "C:\\CUWCDFileStorage\\temp\\test.png";
    var bytes = File.ReadAllBytes(file);
    using (var stream = File.Open(file, FileMode.Open))
    {
        Console.WriteLine(Sha1HashFile(bytes));   // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80
        Console.WriteLine(Sha1HashFile(stream));  // Returns DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
        Console.WriteLine(Sha1HashFile2(bytes));  // Returns B7F6D90C30233F91FCEFE05FB49679F8B26C9D80
    }

    Console.Read();
}

public static string Sha1HashFile(byte[] file)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", "");
    }
}

public static string Sha1HashFile(Stream stream)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", "");
    }
}

public static string Sha1HashFile2(byte[] bytes)
{
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png";
    File.WriteAllBytes(file, bytes);
    return Sha1HashFile(File.OpenRead(file));
}

我什至尝试将字节数组放入MemoryStreamnew MemoryStream(bytes),但这也不起作用。似乎一旦我将文件放在字节数组中,它就无法放回。

编辑:

我从示例中删除了一些代码,因为我认为 MD5 可以正常工作。这是我用来测试的原始代码:

static void Main(string[] args)
{
    string file = "C:\\CUWCDFileStorage\\temp\\test.png";
    var bytes = File.ReadAllBytes(file);
    using (var stream = File.Open(file, FileMode.Open))
    {
        Console.WriteLine(Md5HashFile(bytes));
        Console.WriteLine(Md5HashFile(stream));
        Console.WriteLine(Sha1HashFile(bytes));
        Console.WriteLine(Sha1HashFile(stream));
        Console.WriteLine(Sha1HashFile2(bytes));
    }

    Console.Read();
}

public static string Md5HashFile(byte[] file)
{
    using (MD5 md5 = MD5.Create())
    {
        return BitConverter.ToString(md5.ComputeHash(file)).Replace("-", "");
    }
}

public static string Sha1HashFile(byte[] file)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", "");
    }
}

public static string Md5HashFile(Stream stream)
{
    using (MD5 md5 = MD5.Create())
    {
        return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "");
    }
}

public static string Sha1HashFile(Stream stream)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", "");
    }
}

public static string Sha1HashFile2(byte[] bytes)
{
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png";
    File.WriteAllBytes(file, bytes);
    return Sha1HashFile(File.OpenRead(file));
}

有关问题的解释,请参阅下面的答案。

【问题讨论】:

  • 您问题中提供的代码是实际的真实代码吗?您是否尝试过完全按照此处编写的方式运行代码?因为,您问题中的代码示例很好,不会产生不同的哈希值...
  • 另外值得注意的是,您列出的第二个哈希是一个空流的哈希。
  • 我想,流可能会跳过一些前导字节。这不太可能,但这是我能想到的最好的。与数组的前 3-4 个字节相比,您可以检查流的前 3-4 个字节吗?它们是一样的吗?
  • @elgonzo 你是对的。下面的例子是我实际测试的,现在我知道问题出在哪里了。

标签: c# sha1


【解决方案1】:

问题是在第一种方式散列时,流被读取到最后。这导致第二个哈希是错误的。因此,我需要为第二个散列重新打开一个流,或者在散列第二种方式之前将流倒回到开头。这是解决方案:

static void Main(string[] args)
{
    string file = "C:\\CUWCDFileStorage\\temp\\test.png";
    var bytes = File.ReadAllBytes(file);
    using (var stream = File.Open(file, FileMode.Open))
    {
        Console.WriteLine(Md5HashFile(bytes));
        Console.WriteLine(Md5HashFile(stream));
    }

    using (var stream = File.Open(file, FileMode.Open))
    {
        Console.WriteLine(Sha1HashFile(bytes));
        Console.WriteLine(Sha1HashFile(stream));
        Console.WriteLine(Sha1HashFile2(bytes));
    }

    Console.Read();
}

public static string Md5HashFile(byte[] file)
{
    using (MD5 md5 = MD5.Create())
    {
        return BitConverter.ToString(md5.ComputeHash(file)).Replace("-", "");
    }
}

public static string Sha1HashFile(byte[] file)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        return BitConverter.ToString(sha1.ComputeHash(file)).Replace("-", "");
    }
}

public static string Md5HashFile(Stream stream)
{
    using (MD5 md5 = MD5.Create())
    {
        return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "");
    }
}

public static string Sha1HashFile(Stream stream)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        return BitConverter.ToString(sha1.ComputeHash(stream)).Replace("-", "");
    }
}

public static string Sha1HashFile2(byte[] bytes)
{
    string file = "C:\\CUWCDFileStorage\\temp\\test2.png";
    File.WriteAllBytes(file, bytes);
    return Sha1HashFile(File.OpenRead(file));
}

【讨论】:

    猜你喜欢
    • 2012-02-22
    • 2012-06-01
    • 2010-12-03
    • 1970-01-01
    • 2013-08-24
    • 2019-02-24
    • 2021-12-11
    • 2012-04-10
    • 2010-10-08
    相关资源
    最近更新 更多