在流上腌制C#MD5 ComputeHash

Kei*_*rsh 3 c# hash md5 stream salt

我看不出任何方法来加密MD5.ComputeHash(Stream).我错过了一些将字节注入HashAlgorithm的方法吗?

我在执行流计算之前尝试执行ComputeHash(byte []),但不出所料,它没有任何效果.任何想法(除了修改文件)?

谢谢你的时间.

附录 只是为了更具体一点,我想使用一个流来获取一个我不想加载到内存中的大文件的哈希值.

FileInfo myFI= new FileInfo("bigfile.dat");
FileStream myIFS = piFile.OpenRead();
MD5 md5 = MD5.Create();
byte[] hash = md5.ComputeHash ( myIFS );
myIFS.Close ();
Run Code Online (Sandbox Code Playgroud)

bbm*_*mud 6

在我看来,缺乏例子的答案是:你真的不需要加盐.

像MD5这样的散列算法采用任意长度的字节表,并将其转换为已知长度的字节表 - 操作不容易反转,输入表的小变化会导致输出表中出现不可预测的变化:

input => MD5 =>输出

salting的目的是防止攻击,其中用户已经预先计算了哈希结果(彩虹表).通过在输入中引入微小的变化,结果会发生巨大变化,因此即使攻击者知道散列结果和盐,也很难猜测输入:

输入+盐=> MD5 =>输出

散列文件的原因是计算校验和.例如,您在网页上发布文件以及哈希结果.然后,用户下载文件,通过MD5运行,并将结果与​​发布的结果进行比较.篡改文件非常困难,因为每次操作都会改变生成的哈希值.

这里不需要Salting,因为您必须使用生成的哈希发布salt,以便用户可以重复哈希操作.

如果你真的需要引入salting,只需以可重复的方式更改输入流,例如为每个字节添加一个(带溢出).

  • 我仍然不清楚这个评论.您希望将"哈希"存储在"打开"中,并防止攻击者通过保持盐的秘密来改变它.但人们需要知道盐才能验证散列.听起来真正想要的是数字签名.(虽然让攻击者更改任何类型的完整性凭据会打开一个非常明显的拒绝服务漏洞.) (3认同)

DxC*_*xCK 5

这是正确的方法:

    private static byte[] _emptyBuffer = new byte[0];

    public static byte[] CalculateMD5(Stream stream)
    {
        return CalculateMD5(stream, 64 * 1024);
    }

    public static byte[] CalculateMD5(Stream stream, int bufferSize)
    {
        MD5 md5Hasher = MD5.Create();

        byte[] buffer = new byte[bufferSize];
        int readBytes;

        while ((readBytes = stream.Read(buffer, 0, bufferSize)) > 0)
        {
            md5Hasher.TransformBlock(buffer, 0, readBytes, buffer, 0);
        }

        md5Hasher.TransformFinalBlock(_emptyBuffer, 0, 0);

        return md5Hasher.Hash;
    }
Run Code Online (Sandbox Code Playgroud)