我正在使用cryptonite在CTR模式下执行AES256加密。到目前为止,ByteStrings的一切工作正常,但为了更好的空间效率(有些文件可能很大),我想切换到懒惰的IO和懒惰的ByteStrings。
cryptonite包中ctrCombine的类型签名是:
y >= N
问题是:ByteString.Lazy不是ByteArray的实例。如果我尝试将懒惰的ByteString传递给ctrCombine,GHC会抱怨以下错误:
ctrCombine :: ByteArray ba => cipher -> IV cipher -> ba -> ba
是否可以使用cryptonite执行延迟加密?或者是否有一些实现ByteArray for lazy ByteStrings的包?还是我错过了一些明显的东西?我可以轻松地编写我自己的ctrCombine版本,它基于ecbEncrypt,它运行在懒惰的ByteStrings上,特别是因为AES非常适合流媒体,但我不想重新发明轮子。 (而且,这会违反“不写自己的加密”原则。)
答案 0 :(得分:1)
特定问题的具体答案
是否可以使用cryptonite执行延迟加密? [...]我可以轻松编写我自己的ctrCombine版本,基于ecbEncrypt,它运行在懒惰的ByteStrings上,特别是因为AES非常适合流媒体,但我不想重新发明轮子。
所有的原语都在那里,但正如你所说,它们并没有像你想的那样容易组合。
或者是否有一些实现ByteArray for lazy ByteStrings的包?
我希望不是。作为ByteArray
实例的任何类型也必须是ByteArrayAccess
的实例,因此具有通过withByteArray :: ba -> (Ptr p -> IO a) -> IO a
将整个字节数组放入连续内存中的函数。这与懒惰的字节串相反。让人们先使用Data.ByteString.Lazy.toStrict
更为诚实。
或者我错过了一些明显的东西?
上面提到toStrict
。
(而且,这会违反“不写自己的加密”原则。)
如果你直接使用计数器模式,那么你已经处于许多人会考虑“编写你自己的加密”的水平,即使它不是传统上的格言。
另类
cryptonite API旨在使常见的事情变得更容易,而不是我曾经希望Haskell社区的基础支撑。另一种选择是crypto-api,它更加灵活,代价是对最终用户来说不那么简单。
特定于您的问题:在crypto-api中有一个Crypto.Classes.ctrLazy
函数。其次,即使只有严格的ByteString版本,你也可以利用返回的IV
来构建一个懒惰的计数器模式,而无需借助ECB。
缺乏返回IV,并且在某些情况下使用异常而不是sum类型,我觉得这是Vincent发布的“保持简单简单”API和最大灵活低级别之间的区别的原始点。我在crypto-api和那个时代的其他软件包中推广的API。