我正在编写一个应用程序,我希望能够通过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等纯函数所需的随机数生成器的最佳选择是什么?
答案 0 :(得分:1)
我建议使用CPRG实例池,如果数字表示你需要这个。可能首先要做一些基本的分析,看看简单的atomicModifyIORef方法是否会成为瓶颈。
对于池,您可以使用http://hackage.haskell.org/package/resource-pool或http://hackage.haskell.org/package/pool-conduit(基于资源池)。