Объединять или не объединять поставщиков услуг криптографии Java
Я сталкиваюсь с регулярной дилеммой при кодировании безопасностирамки : "объединять или не объединять"
В основном этот вопрос разделен на две «группы»:
Группа 1 :SecureRandom
потому что призыв кnextBytes(...)
синхронизируется, и это может стать узким местом для WebApp / многопоточного приложения
Группа 2: поставщики крипто-услуг, такие какMessageDigest
, Signature
, Cipher
, KeyFactory
, ... (из-за стоимостиgetInstance()
?)
Каково твое мнение ?
Какие у вас привычки на такие вопросы?
Изменить 09/07/2013Я наконец нашел время, чтобы проверить @QwerkyShare
Сам по себе, и я нахожу результат довольно ... удивительным.
В классе не хватало моей главной заботы: бассейны любятGenericObjectPool или жеStackObjectPool.
Поэтому я переделал класс, чтобы проверить все 4 варианта:
Единый общий экземпляр с синхронизациейсутьновые экземпляры внутри каждого цикла (меня не интересует случай, когда вы можете вытащить создание дайджеста за пределы цикла)сутьGenericObjectPool:сутьStackObjectPool:сутьМне пришлось снизить количество циклов до 100000, так как 1M занимал слишком много времени с пулами.
Я также добавилThread.yield()
в конце каждой петли, чтобы придать нагрузке более хорошую форму.
Результаты (накопительное время выполнения):
Дайджест сообщенияновые экземпляры: 420 сОдин экземпляр: 550 сStackObjectPool: 800 сGenericObjectPool: 1900 сKeyFactoryновые экземпляры: 400 сОдин экземпляр: 350 сStackObjectPool: 2900 сGenericObjectPool: 3500 сSecureRandomStackObjectPool: 1600 сновые экземпляры: 2300 сGenericObjectPool: 2300 сОдин экземпляр: 2800 сшифроватьStackObjectPool: 2800 сGenericObjectPool: 3500 сОдин экземпляр: 5100 сновые экземпляры: 8000 сЗаключениеДля MessageDigest и KeyFactory пулы являются убийцами производительности и даже хуже, чем один экземпляр с узким местом синхронизации, тогда как они действительно полезны, когда речь идет о SecureRandom и Cipher.