3

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 のような純粋な関数がマルチスレッドのクライアント/サーバー アプリケーションで使用される場合に必要な乱数ジェネレーターを管理するための最適なオプションは何ですか?

4

1 に答える 1

1

CPRGインスタンスのプールを使用することをお勧めします.これが必要な場合は. 単純なatomicModifyIORefアプローチがボトルネックになるかどうかを確認するために、最初にいくつかの基本的なプロファイリングを行う価値があるでしょう。

プールの場合、http://hackage.haskell.org/package/resource-pool、またはhttp://hackage.haskell.org/package/pool-conduit (resource-pool に基づく) を使用できます。

于 2013-04-16T06:33:40.143 に答える