3

有人知道.NET 的 CryptoStream 的可寻找替代品吗?

如果替代方案仅在“读取”模式下支持 Seek 或者仅限于例如 AES256,则可以。

4

3 回答 3

4

逐块加密是完全安全的。只是欧洲央行有问题。可以使用 OFB 或 CTR 模式编写实现。但是,我从来没有设法找到一个。可以硬着头皮写下来……

更新:

所以我确实写了一个实现。由于各种原因,我现在不打算在这里发布它(我会在某个时候尝试发布),但这里有一些建议给任何想要这样做的人:

在 CBC 模式下使用 RijndaelManaged 转换。您将逐块计算密码流。您可以通过在转换中初始化一个键和一个空(全为零)iv 来做到这一点 - 实际的 iv 将逐块计算。

您将需要一种方法,通过连接或以其他方式计算 nonce 加 iv 加计数器来计算当前块的输入。您可以在此处进行多项优化,包括预先计算 nonce 和 iv(此方法将被多次调用,因此可能值得)。

例如 byte[] GetCurrentCounterBlock(byte[] nonce, byte[] iv, UInt32 counter)

(注意:这里的“iv”是指 NIST 所说的 IV,整个区块的中间部分,其他人统称为 IV)

您将在对数据进行加密的循环中使用此方法 - 第一次调用此方法,然后在块边界处调用以更新当前密码流。此方法为变换的 TransformBlock 方法提供输入。从转换中获取输出,并将结果与​​当前数据块进行异或。加密每个块后使用 transform.Reset() !否则,CBC 将尝试使用转换的输出作为下一个转换的输入。使用 .NET 可能有更聪明的方法来做到这一点,但我想不通。我知道 BouncyCastle “本机”支持 OFB,因此这可能是一个更好的选择,但这是在没有外部依赖的情况下获得高度可重用的加密流的好方法。

无论如何,关键是整个方法(我称之为 AesCtr256.Process - 但你可以更容易地更通用)适用于密码流中任意范围的数据。您可以在自定义 Stream 类中轻松使用此方法。这将允许在读取和写入时寻找流内的任意位置,并为您提供字节对齐的数据以使用(真的很好,因为您现在可以拥有一个实际报告真实数据长度的加密流!)。

换句话说,您计算流的任意部分的密码流,然后简单地与密码或纯文本进行异或来加密/解密。

最后两件事:1.) 我强烈建议在流的整个生命周期内重复使用转换 - 创建这些是昂贵的。2.) 如果您要针对 NIST 向量或类似的 . 不要以为你做对了——仅仅因为输出看起来是随机的,并不意味着它被正确加密:)。

如果有人对更好的方法有任何想法,或者我如何完全搞砸了一段非常关键的代码,请发布,谢谢!

于 2009-08-27T18:58:52.107 回答
2

I think such an implementation would not be very useful, as Seek operations can only be performed in (relatively, depending on the algorithm) constant time with ECB-style chaining, i.e. encrypting blocks separately - and that's highly unrecommended - see the image in this Wikipedia article for a startling example of insecurity.

Seems to me you would be better off by copying into / out of a MemoryStream or similar wrapping technique.

于 2009-08-23T10:22:04.670 回答
0

这是一个重复的问题。我把答案放在: 如何向 CryptoStream 添加搜索和定位功能

即使它使用的是欧洲央行,但你可以使用任何其他算法。顺便说一句,它没有巴里凯利提到的欧洲央行问题,因为它使用欧洲央行的方式不同。

于 2016-08-16T12:07:34.443 回答