使用haskell / cryptonite进行延迟操作

时间:2018-01-27 17:09:23

标签: haskell

我正在使用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非常适合流媒体,但我不想重新发明轮子。 (而且,这会违反“不写自己的加密”原则。)

1 个答案:

答案 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。