2013-04-15 2 views
3

웹 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와 같은 순수 함수에 필요한 난수 생성기를 관리하는 가장 좋은 옵션은 무엇입니까?

+0

실제 문제 코드 스 니펫을 제공해 주시겠습니까? 예를 들어, IORef의 생성기, 생성을 사용하는 엔티티 및이 RSA 암호화 루틴이 있습니다. 나는이 단체들이 (단 하나의) RNG에 대해 어떻게 경쟁하고 있는지 명확하지 않다. 참고로 일반적으로 멀티 스레드 환경에서는 스레드 당 하나의 RNG를 갖습니다. –

+0

나는 분노에서 사용 된 AES CPRG를 찾을 수있는 유일한 곳이기 때문에 클라이언트 세션에서 IORef 예제를 언급했습니다. 아마 내가 부르고있는 정확한 코드는별로 중요하지 않습니다. (그리고 나는 그것을 작성하는 가장 좋은 방법을 찾고 있습니다.) 예를 들어 Yesod Handler 함수 (또는 동등한 HTTP 요청 처리 코드)에서'Crypto.PubKey.RSA.OAEP.encrypt'를 호출하려고한다고 가정 해 봅시다. 스레드마다 인스턴스를 관리하는 방법은 내가 찾고있는 것처럼 들리지만, 그렇게하는 코드를 찾지 못했기 때문에 어떤 점을 지적하면 멋질 것입니다. –

답변

1

번호가 인 경우 CPRG 인스턴스 풀 을 사용할 것을 권장합니다. 간단한 atomicModifyIORef 접근 방식이 병목 현상이 될지 알아보기 위해 먼저 몇 가지 기본 프로파일 링을 수행 할 가치가 있습니다.

풀의 경우 http://hackage.haskell.org/package/resource-pool 또는 http://hackage.haskell.org/package/pool-conduit (resource-pool을 기반으로 함)을 사용할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 실제 응용 프로그램이 아니기 때문에 아직 숫자는 없지만 심폐 소생술을 필요로하는 함수 위에 복잡한 API를 작성할 때 문제가 될 수 있습니다. 이 접근법을 사용하여 화해 할 수없는 또 다른 사실은 이론적으로 암호화 호출이 얼마나 많은 데이터를 사용하는지 모르기 때문에 'ClientSession'으로 바이트 수를 유지함으로써 생성기의 재 시드를 관리하면 ' 가능할 수 있습니다.더 자세히 살펴보면 CPRG 인스턴스는'cprgNeedReseed'를 통해 내부 상태를 사용할 수있게 만들어서 사용할 수 있습니다. –