Web API を介して RSA 暗号化トークンをクライアントに提供できるようにするアプリケーションを作成しています。
たとえば、RSAのcrypto-pubkey
ライブラリを使用しています:
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 カウンター モードの実装を提供するライブラリをCPRG
使用して、インスタンスを作成できます。cprng-aes
makeSystem :: IO AESRNG
これは、Yesod がそのClientSession
モジュールで使用するのと同じ実装です。私はそれを見て、グローバルインスタンスを背後に格納し、それを使用して、呼び出しIORef
内で初期化ベクトルを生成する関数を実装します。atomicModifyIORef
関数はジェネレーターからいくつかのバイトを取り出して返し、新しい CPRG インスタンスを IORef に書き戻すだけなので、これは問題ありません。ただし、RSA API は CPRG
インスタンスに直接渡す必要があり、たとえ の呼び出し内でトークン生成を実行できたatomicModifyIORef
としても、はるかにコストのかかる操作になり、競合の問題につながる可能性があります。
私が持っていた 1 つのアイデアは、暗号化 API を呼び出す前に事前にグローバル インスタンスから適切なデータを引き出し、それCPRG
を によってバックアップされたインスタンスにラップすることByteString
でしたが、これは内部の事前知識が必要なため、少し脆弱なハックです。トークン生成プロセス - コンテンツ キーのサイズ、RSA パディングなど。選択したパラメーターによって異なる場合があります。
上記の RSA API のような純粋な関数がマルチスレッドのクライアント/サーバー アプリケーションで使用される場合に必要な乱数ジェネレーターを管理するための最適なオプションは何ですか?