gpt4 book ai didi

c# - 将 IV 添加到 CryptoStream 的开头

转载 作者:太空宇宙 更新时间:2023-11-03 20:56:10 25 4
gpt4 key购买 nike

我正在现有文件管理程序中实现本地加密。

我可以找到很多示例代码,例如 Microsoft's ,演示了如何直接写入文件,但我需要做的是提供一个在程序其他地方使用的流:

CryptoStream GetEncryptStream(string filename)
{
var rjndl = new RijndaelManaged();
rjndl.KeySize = 256;
rjndl.BlockSize = 256;
rjndl.Mode = CipherMode.CBC;
rjndl.Padding = PaddingMode.PKCS7;

// Open read stream of unencrypted source fileStream:
var fileStream = new FileStream(filename, FileMode.Open);

/* Get key and iv */

var transform = rjndl.CreateEncryptor(key, iv);

// CryptoStream in *read* mode:
var cryptoStream = new CryptoStream(fileStream, transform, CryptoStreamMode.Read);

/* What can I do here to insert the unencrypted IV at the start of the
stream so that the first X bytes returned by cryptoStream.Read are
the IV, before the bytes of the encrypted file are returned? */

return cryptoStream; // Return CryptoStream to be consumed elsewhere
}

我的问题在最后一行的评论中有所概述,但有一个:我如何将 IV 添加到 CryptoStream 的开头,以便它成为读取 CryptoStream 时返回的第一个 X 字节,考虑到何时控制真正开始读取流并写入文件超出了我的代码范围?

最佳答案

好的...既然您的问题很清楚,它“相当”简单...遗憾的是 .NET 不包含合并两个 Stream 的类,但我们可以轻松创建它. MergedStream 是一个只读、只进的多流合并器。

你像这样使用:

var mergedStream = new MergedStream(new Stream[] 
{
new MemoryStream(iv),
cryptoStream,
});

现在...当有人试图从 MergedStream 读取数据时,首先会消耗包含 IV 的 MemoryStream,然后是 cryptoStream将被消耗。

public class MergedStream : Stream
{
private Stream[] streams;
private int position = 0;
private int currentStream = 0;

public MergedStream(Stream[] streams) => this.streams = streams;

public override bool CanRead => true;

public override bool CanSeek => false;

public override bool CanWrite => false;

public override long Length => streams.Sum(s => s.Length);

public override long Position
{
get => position;
set => throw new NotSupportedException();
}

public override void Flush()
{
}

public override int Read(byte[] buffer, int offset, int count)
{
if (streams == null)
{
throw new ObjectDisposedException(nameof(MergedStream));
}

if (currentStream >= streams.Length)
{
return 0;
}

int read;

while (true)
{
read = streams[currentStream].Read(buffer, offset, count);
position += read;

if (read != 0)
{
break;
}

currentStream++;

if (currentStream == streams.Length)
{
break;
}
}

return read;
}

public override long Seek(long offset, SeekOrigin origin)
=> throw new NotSupportedException();

public override void SetLength(long value)
=> throw new NotSupportedException();

public override void Write(byte[] buffer, int offset, int count)
=> throw new NotSupportedException();

protected override void Dispose(bool disposing)
{
try
{
if (disposing && streams != null)
{
for (int i = 0; i < streams.Length; i++)
{
streams[i].Close();
}
}
}
finally
{
streams = null;
}
}
}

关于c# - 将 IV 添加到 CryptoStream 的开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50445749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com