写入流时计算哈希值

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

在.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); } 

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

所以基本上我只需要处理一次数据。 在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); } 

显然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); } 

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

是否可以使用.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); } 

这是由CryptoStream为您完成的。

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

您可以使用HashAlgorithm.TransformBlock进行逐块哈希变换。 这可以包含在Stream实现中,因此您可以按照建议使用HashStream 。 记得在获取哈希值之前调用TransformFinalBlock 。

HashAlgorithm是抽象的,所以当然你需要选择你想要的具体实现。 有MD5,SHA系列和其他可供选择。