Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 写入流时计算哈希_C#_.net_Stream_Cryptography_Hash - Fatal编程技术网

C# 写入流时计算哈希

C# 写入流时计算哈希,c#,.net,stream,cryptography,hash,C#,.net,Stream,Cryptography,Hash,我目前正在创建需要签名的加密文件格式。 为此,我需要计算已写入流的内容的哈希代码 在.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(c

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

在.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实现为流的项目,该流在每次有写入数据时计算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);
}

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);
}
显然,CRC32不是一个散列算法,但最好有一个类似于采用散列算法的散列流的东西。HashStream将在每次调用write/read时更新哈希值

比如:

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

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可以采用哈希算法。因此,对于同时加密和散列,我可以这样做:

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

可以使用进行逐块哈希转换。这可以包装在流实现中,因此您可以按照您的建议使用
HashStream
。记住在获取散列值之前调用


HashAlgorithm是抽象的,因此当然需要选择您想要的具体实现。有MD5、SHA家族和其他人可供选择。

它由CryptoStream为您完成

SHA256 hashAlg=new SHA256Managed();
CryptoStream cs=新的CryptoStream(_out,hashAlg,CryptoStreamMode.Write);
//在此处写入数据
cs.FlushFinalBlock();
字节[]哈希=hashAlg.hash;

我想你应该谨慎行事,在
cryptStream.FlushFinalBlock()之后调用
hashStream.FlushFinalBlock()
我试过了,但它抛出了一个异常。显然,FlushFinalBlock也在基流上调用。即使它被声明为流。对加密流调用了System.NotSupportedException Message=FlushFinalBlock()方法两次。它只能调用一次。您不必显式调用
FlushFinalBlock
。say“调用
Close
方法将调用
FlushFinalBlock
”,因此在关闭
using
后,
cryptoHash.Hash
将具有哈希值。您知道在读取或写入期间计算哈希的sync/async流包装器的良好实现吗?