Java 9-15: PFX вместо JKS
Версии Java, начиная с версии 9, больше не используют проприетарный тип хранилища ключей JKS. Вместо этого они по умолчанию используют типы хранилищ ключей PKCS#12, также известные как файлы PFX.
Эти хранилища ключей защищены отдельными механизмами получения ключей PBKDF для обеспечения целостности хранилища ключей, закрытых ключей и сертификатов.
Используемые алгоритмы
Целостность всего хранилища ключей по умолчанию защищена с помощью HMAC-SHA-1, который по-прежнему является безопасным, несмотря на использование алгоритма хеширования, для которого могут генерироваться коллизии. Опять же, это может быть не тот алгоритм, который вы все еще используете для аудиторов.
Сами ключи защищены с помощью 3-х ключевого тройного DES. Здесь возникает та же проблема, поскольку тройной DES с тремя ключами по-прежнему предлагает около 112 бит безопасности в таких сценариях. В настоящее время вы, конечно, предпочитаете использовать AES-256, особенно когда речь идет о защите закрытых ключей.
Сертификаты защищены с помощью 40-битного RC2. По сути, я бы назвал это запутыванием, а не фактическим шифрованием. К счастью, целостность всего хранилища ключей в любом случае защищена, а сертификаты обычно считаются общедоступными. Однако, если вы (все еще) считаете, что переключение открытых и закрытых ключей — это хорошая идея, то вас ждет (еще один) большой сюрприз.
Шифрование на основе пароля (PBE)
PBE означает, что ключи, используемые для обеспечения (целостности и) конфиденциальности, рассчитываются на основе пароля. Эти пароли могут быть атакованы с помощью автономной атаки после того, как злоумышленник завладел файлом хранилища ключей.
Безопасность шифрования на основе пароля зависит главным образом от безопасности используемого пароля или парольной фразы. Если это всего 6 символов (минимум, который, по-видимому, принимает keytool
), то, как правило, безопасность не обеспечивается. Если энтропия на символ равна 6 битам, то вся безопасность равна 6 x 6 = 36 битам.
Однако PBKDF указывает количество итераций, в течение которых пароль и соль хэшируются, прежде чем они будут использоваться в качестве ключа. Это добавляет немного безопасности. Однако keytool
использует не менее 50 000 итераций, тогда как в настоящее время рекомендуется не менее миллиона итераций. 50 000 итераций добавляют к общему количеству еще 15/16 бит безопасности. Это хорошо, но с полностью случайным паролем из 6 символов вы все равно застряли бы на 50 битах безопасности.
Что еще хуже, кажется, что PKCS # 12 использует гораздо больше итераций для вычисления различных ключей для ключей HMAC, 3DES и RC2. Это означает, что обычному пользователю на самом деле приходится выполнять намного больше работы с каждым паролем, чтобы вычислить ключи, в то время как злоумышленнику нужно только вычислить 40-битный ключ RC2, чтобы проверить правильность предположения. Кроме того, реализация Java в PBKDF определенно не самая быстрая. В конце концов, вы не можете полагаться на PBKDF, чтобы повысить безопасность используемого пароля. К счастью, хранилище ключей загружается один раз; после этого он сохраняется в памяти.
В конце концов, формат хранилища ключей PFX ужасно устарел, как и реализация Java keytool
и PKCS12KeyStore
. Единственный способ оставаться в достаточной безопасности — это использовать генератор паролей и хранилище паролей (например, KeyPass`) для создания действительно надежного пароля. Рекомендуется использовать 12 рандомизированных символов с использованием буквенно-цифрового алфавита (прописные, строчные и цифры). Это дает примерно 12 x ~6 + ~16 = ~88 бит безопасности.
Доказательство
Итак, давайте проверим все это:
keytool -genkeypair -alias test -keyalg RSA -keysize 4096 -sigalg SHA256withRSA -keystore test.pfx
а потом
openssl pkcs12 -info -in test.pfx
приводит к:
MAC: sha1, Iteration 100000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000
Bag Attributes
friendlyName: test
localKeyID: 54 69 6D 65 20 31 36 31 34 39 34 35 39 34 35 38 32 33
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
<PKCS8ShroudedKeyBag in base 64>
-----END ENCRYPTED PRIVATE KEY-----
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000
Certificate bag
Bag Attributes
friendlyName: test
localKeyID: 54 69 6D 65 20 31 36 31 34 39 34 35 39 34 35 38 32 33
subject=C = Unknown, ST = Unknown, L = Unknown, O = Unknown, OU = Unknown, CN = Test
issuer=C = Unknown, ST = Unknown, L = Unknown, O = Unknown, OU = Unknown, CN = Test
-----BEGIN CERTIFICATE-----
<base 64 encoded self-signed certificate>
-----END CERTIFICATE-----
Не думайте о безопасности
Хотите лучше защитить свои ключи, тогда обратитесь к консультанту по безопасности. Тот факт, что весь мир использует keytool
, не обязательно делает его безопасным, как мы показали здесь. Здесь (даже) больше вопросов, чем ответов.
person
Maarten Bodewes
schedule
05.03.2021