웹 API를 통해 클라이언트에 RSA 암호화 토큰을 제공 할 수있는 응용 프로그램을 작성하고 있습니다.Haskell 웹 응용 프로그램에서 암호화 난수 생성기 관리
내가 예를 들어, RSA에 대한 crypto-pubkey
library을 사용하고 있습니다 : 내 경우
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 콘텐츠 키입니다. I는 AES 카운터 모드 구현을 제공하는 cprng-aes
라이브러리를 사용 CPRG
인스턴스를 생성 할 수 Yesod 그 ClientSession
모듈에서 사용하는 것과 같은 구현은
makeSystem :: IO AESRNG
한다. 나는 이것을 살펴본 후 IORef
뒤에 글로벌 인스턴스를 저장하고 이것을 atomicModifyIORef
호출 내에서 초기화 벡터를 생성하는 함수를 구현하는 데 사용합니다.
이 함수는 일부 바이트를 생성기에서 꺼내 반환하고 새 CPRG 인스턴스를 IORef에 다시 쓰므로 괜찮습니다. 그러나 RSA API는 CPRG
인스턴스를 직접 전달해야하며 atomicModifyIORef
에 대한 호출 내에서 토큰 생성을 수행 할 수 있다고해도 비용이 많이 드는 작업이며 경합 문제가 발생할 수 있습니다.
암호화 API를 호출하기 전에 사전에 글로벌 인스턴스에서 적절한 데이터를 꺼내서 인스턴스 (예 : ByteString
)로 마무리하는 것이 하나의 아이디어였습니다.하지만 이는 매우 취약한 해킹입니다. 토큰 생성 과정의 내부 지식 (내용 키 크기, RSA 패딩 등)은 선택한 매개 변수에 따라 다를 수 있습니다.
멀티 스레드 클라이언트 - 서버 응용 프로그램에서 위의 RSA API와 같은 순수 함수에 필요한 난수 생성기를 관리하는 가장 좋은 옵션은 무엇입니까?
실제 문제 코드 스 니펫을 제공해 주시겠습니까? 예를 들어, IORef의 생성기, 생성을 사용하는 엔티티 및이 RSA 암호화 루틴이 있습니다. 나는이 단체들이 (단 하나의) RNG에 대해 어떻게 경쟁하고 있는지 명확하지 않다. 참고로 일반적으로 멀티 스레드 환경에서는 스레드 당 하나의 RNG를 갖습니다. –
나는 분노에서 사용 된 AES CPRG를 찾을 수있는 유일한 곳이기 때문에 클라이언트 세션에서 IORef 예제를 언급했습니다. 아마 내가 부르고있는 정확한 코드는별로 중요하지 않습니다. (그리고 나는 그것을 작성하는 가장 좋은 방법을 찾고 있습니다.) 예를 들어 Yesod Handler 함수 (또는 동등한 HTTP 요청 처리 코드)에서'Crypto.PubKey.RSA.OAEP.encrypt'를 호출하려고한다고 가정 해 봅시다. 스레드마다 인스턴스를 관리하는 방법은 내가 찾고있는 것처럼 들리지만, 그렇게하는 코드를 찾지 못했기 때문에 어떤 점을 지적하면 멋질 것입니다. –