在Haskell Web应用程序中管理加密随机数生成器

时间:2013-04-15 20:48:13

标签: haskell yesod

我正在编写一个应用程序,我希望能够通过Web API向客户提供RSA加密令牌。

我正在使用crypto-pubkey library进行RSA,例如:

encrypt :: CPRG g
    => g          -- ^ random number generator.
    -> OAEPParams -- ^ OAEP params to use for encryption.
    -> PublicKey  -- ^ Public key.
    -> ByteString -- ^ Message to encrypt
    -> (Either Error ByteString, g)

就我而言,消息是用于加密令牌的AES内容密钥。我可以使用提供AES计数器模式实现的cprng-aes库创建CPRG实例:

makeSystem :: IO AESRNG

与Yesod在其ClientSession模块中使用的实现相同。我已经看了一下它,它在IORef后面存储了一个全局实例,并用它来实现一个函数,用于在atomicModifyIORef调用中生成初始化向量。

这没关系,因为函数只是将一些字节从生成器中拉出并返回它们,将新的CPRG实例写回IORef。但是,RSA API需要直接传递CPRG个实例,即使我可以在atomicModifyIORef的调用中执行我的令牌生成,也可能是一个成本高得多的操作并导致争用的问题。

我有一个想法是在调用加密API之前提前从全局实例中提取足够的数据,并将其包装在由CPRG支持的ByteString实例中,但这有点脆弱的黑客,因为它需要先前知道令牌生成过程的内部 - 内容密钥大小,RSA填充等,这可能会根据所选参数而有所不同。

在多线程客户端 - 服务器应用程序中使用上述RSA API等纯函数所需的随机数生成器的最佳选择是什么?

1 个答案:

答案 0 :(得分:1)

我建议使用CPRG实例池,如果数字表示你需要这个。可能首先要做一些基本的分析,看看简单的atomicModifyIORef方法是否会成为瓶颈。

对于池,您可以使用http://hackage.haskell.org/package/resource-poolhttp://hackage.haskell.org/package/pool-conduit(基于资源池)。