写入流时计算哈希值

sor*_*sen 13 .net c# hash cryptography stream

我目前正在创建需要签名的加密文件格式.为此,我需要计算我写入流的内容的哈希码.

在.net框架中有许多可以使用的哈希算法,并且它工作正常,但它需要我处理流三次.

byte[] content = new byte[] { 0, 1, 2, 3, 4, 5, 6 };

using (Stream fileStream = File.Open("myfile.bin", FileMode.Create))
{
    //Write content
    fileStream.Write(content, 0, content.Length);
}

byte[] hashValue = null;
using (Stream fileStream = File.Open("myfile.bin", FileMode.Open))
{
    HashAlgorithm hash = SHA256.Create();
    hashValue = hash.ComputeHash(fileStream);
}

using (Stream fileStream = File.Open("myfile.bin", FileMode.Append))
{
    fileStream.Write(hashValue, 0, hashValue.Length);
}
Run Code Online (Sandbox Code Playgroud)

如果它被加密到文件,这是可以的,但如果它被加密到网络目的地,则字节不再可用.

所以基本上我只需要处理一次数据.在CodeProject上有一篇文章已经将CRC32实现为Stream,每次有写入数据时都会计算CRC32代码.

就像是:

byte[] content = new byte[] { 0, 1, 2, 3, 4, 5, 6 };

using (FileStream fileStream = File.Create("myfile.bin"))
using (Stream crcStream = new CRCStream(fileStream)) //Takes a base stream
{
    //Write content
    crcStream.Write(content, 0, content.Length); 

    //Write checksum
    fileStream.Write(crcStream.WriteCRC, 0, 4);
}

Run Code Online (Sandbox Code Playgroud)

显然CRC32不是哈希算法,但是像HashStream那样采用HashAlgorithm会更好.每次调用write/read时,HashStream都会更新哈希值.

就像是:

byte[] content = new byte[] { 0, 1, 2, 3, 4, 5, 6 };

HashAlgorithm hashAlgo = SHA256.Create();

using (FileStream fileStream = File.Create("myfile.bin"))
using (HashStream hashStream = new HashStream(hashAlgo, fileStream))
{
    //Write content to HashStream 
    hashStream.Write(content, 0, content.Length);

    //Write checksum
    fileStream.Write(hashStream.HashValue, 0, hashAlgo.HashSize / 8);
}
Run Code Online (Sandbox Code Playgroud)

读取文件应该以类似的方式工作,因此当您读取文件(不包括哈希)时,已经计算了读取内容的哈希值.

是否可以使用.net框架现有组件构建这样的东西?

编辑:

谢谢彼得!我不知道CryptoStream可以采用HashAlgorithm.因此,对于同时加密和散列,我可以这样做:

byte[] content = new byte[] { 0, 1, 2, 3, 4, 5, 6 };

SymmetricAlgorithm cryptoSymetric = Aes.Create();
HashAlgorithm cryptoHash = SHA256.Create();

using (FileStream file = new FileStream("Crypto.bin", FileMode.Create, FileAccess.Write))
using (CryptoStream hashStream = new CryptoStream(file, cryptoHash, CryptoStreamMode.Write))
using (CryptoStream cryptStream = new CryptoStream(hashStream, cryptoSymetric.CreateEncryptor(), CryptoStreamMode.Write))
{
    cryptStream.Write(content, 0, content.Length);
    cryptStream.FlushFinalBlock();

    byte[] hashValue = cryptoHash.Hash;

    file.Write(hashValue, 0, hashValue.Length);
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*lor 39

这是由CryptoStream为您完成的.

SHA256 hashAlg = new SHA256Managed();
CryptoStream cs = new CryptoStream(_out, hashAlg, CryptoStreamMode.Write);
// Write data here
cs.FlushFinalBlock();
byte[] hash = hashAlg.Hash;
Run Code Online (Sandbox Code Playgroud)