Управление на криптографски генератори на случайни числа в уеб приложение на Haskell

Пиша приложение, което искам да мога да доставя RSA криптирани токени на клиенти чрез уеб API.

Използвам crypto-pubkey библиотека за 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 съдържание, използван за криптиране на токена. Мога да създам CPRG екземпляр, използващ cprng-aes библиотеката, която осигурява реализация на AES режим на брояч:

makeSystem :: IO AESRNG

което е същата реализация, която Yesod използва в своя ClientSession модул. Разгледах го и той съхранява глобален екземпляр зад IORef и го използва за прилагане на функция за генериране на вектори за инициализация в atomicModifyIORef повикване.

Това е ОК, тъй като функцията просто изтегля някои байтове от генератора и ги връща, записвайки новия CPRG екземпляр обратно в IORef. RSA API обаче трябва да бъде предадено директно на CPRG екземпляр и дори ако мога да извърша своето генериране на токени в рамките на повикване към atomicModifyIORef, това вероятно ще бъде много по-скъпа операция и ще доведе до проблеми със спора.

Една идея, която имах, беше да изтегля адекватни данни от глобален екземпляр предварително, преди да извикам API за криптиране, и да го увия в CPRG екземпляр, подкрепен от ByteString, но това е малко крехък хак, тъй като изисква предварително познаване на вътрешността на процеса на генериране на токени -- размерът на ключа за съдържанието, подложката на RSA и така нататък, което може да варира в зависимост от избраните параметри.

Кои са най-добрите опции за управление на генераторите на произволни числа, изисквани от чисти функции като горния RSA API, когато се използват в многонишкови приложения клиент-сървър?


person Shaun the Sheep    schedule 15.04.2013    source източник
comment
Бихте ли предоставили фрагмент от действителния код на проблема? Като например имате генератор в IORef, обект, използващ генерирането, и тази процедура за криптиране на RSA. Не ми е ясно как тези субекти се борят за (само един?) RNG. FYI, обикновено в многонишкова среда ще имате един RNG на нишка.   -  person Thomas M. DuBuisson    schedule 16.04.2013
comment
Просто имах предвид примера на IORef в клиентска сесия, тъй като това е единственото място, където мога да намеря AES CPRG, използван в гняв. Точният код, който извиквам, вероятно няма особено значение (и все още измислям най-добрия начин да го напиша). Нека просто кажем, че искам да извикам Crypto.PubKey.RSA.OAEP.encrypt във функция за обработка на Yesod например (или еквивалентен код за обработка на HTTP заявки). Как да управлявам екземпляр на нишка звучи като това, което търся, но не намерих код, който да прави това, така че ако можете да ме насочите към някои, ще бъде страхотно.   -  person Shaun the Sheep    schedule 16.04.2013


Отговори (1)


Бих препоръчал да използвате набор от CPRG екземпляри, ако числата показват, че имате нужда от това. Вероятно си струва първо да направите основно профилиране, за да видите дали простият подход atomicModifyIORef би бил тясно място.

За пулове можете да използвате http://hackage.haskell.org/package/resource-pool или http://hackage.haskell.org/package/pool-conduit (който се основава на ресурсен пул).

person Michael Snoyman    schedule 16.04.2013
comment
Благодаря за отговора. Все още няма цифри, защото това не е приложение от реалния свят :-), но виждам, че може да е проблем при изграждането на по-сложен API върху функции, които изискват CPRG. Друго нещо, с което не можах да се примиря с използването на този подход е, че на теория не знам колко данни използва едно шифровано повикване, така че управлението на повторното зареждане на генератора чрез поддържане на броя на байтовете, както прави ClientSession, не би било възможен. При по-внимателно разглеждане обаче екземплярът на CPRG прави вътрешното си състояние достъпно чрез cprgNeedReseed, така че мога да използвам това. - person Shaun the Sheep; 16.04.2013