Как keytool защищает ключи?

Когда вы создаете хранилище ключей с помощью утилиты Java Keytool, как ключи защищены? Я прочитал документацию и понял, что у каждого закрытого ключа есть ключевой пароль, а затем у хранилища есть пароль хранилища.

Но какой механизм используется для защиты данных? Это шифровальный шифр? Если да, то каков алгоритм? Я сосредоточен конкретно на том, как keytool обеспечивает защиту при создании файла JKS.


person bethlakshmi    schedule 23.12.2009    source источник


Ответы (3)


Примечание Версии Java, начиная с Java 9, по умолчанию используют тип хранилища ключей PKCS#12, а не JKS.


Хранилище ключей Sun JKS по умолчанию использует проприетарный алгоритм, прежде всего для того, чтобы обойти ограничения экспорта для стандартных алгоритмов. Алгоритм реализован в этом классе,

  sun.security.provider.KeyProtector

Это описание алгоритма,

Это реализация запатентованного Sun экспортируемого алгоритма, предназначенного для использования при защите (или восстановлении версии открытого текста) конфиденциальных ключей. Этот алгоритм не предназначен для использования в качестве шифра общего назначения. Вот как работает алгоритм защиты ключа: p - пароль пользователя s - случайная соль X - ключ xor P - ключ, который нужно защитить Y - защищенный ключ R - что хранится в хранилище ключей Шаг 1: Возьмите пароль пользователя, добавьте к нему случайную соль (фиксированного размера) и хешируйте ее: d1 = дайджест(p, s) Сохраните d1 в X. Шаг 2: возьмите пароль пользователя, добавьте результат дайджеста из предыдущего шага и хешируйте его: dn = дайджест (p, dn-1). Сохраните dn в X (добавьте его к ранее сохраненным дайджестам). Повторяйте этот шаг до тех пор, пока длина X не совпадет с длиной закрытого ключа P. Шаг 3: XOR X и P и сохраните результат в Y: Y = X XOR P. Шаг 4: Сохраните s, Y и дайджест(p , P) в буфере результатов R: R = s + Y + дайджест(p, P), где + обозначает конкатенацию. (ПРИМЕЧАНИЕ: дайджест (p, P) сохраняется в буфере результатов, поэтому, когда ключ восстановлен, мы можем проверить, действительно ли восстановленный ключ соответствует исходному ключу.) R хранится в хранилище ключей. Защищенный ключ восстанавливается следующим образом: Шаг 1 и Шаг 2 такие же, как и выше, за исключением того, что соль генерируется не случайным образом, а берется из результата R шага 4 (первая длина(ы) байтов). Шаг 3 (операция XOR) дает открытый текстовый ключ. Затем соедините пароль с восстановленным ключом и сравните с последним значением length(digest(p, P)) байтов R. Если они совпадают, восстановленный ключ действительно совпадает с исходным ключом.

person ZZ Coder    schedule 23.12.2009

Используемый алгоритм зависит от используемого хранилища ключей (например, это может быть смарт-карта).

Хранилище ключей по умолчанию, которое Sun поставляет с JDK, создает программный токен (в файле на диске) с три варианта шифрования:

  1. по умолчанию: "jks", собственный тип (формат) хранилища ключей. Не уверен в алгоритме.

  2. «jceks», альтернативный проприетарный формат, использующий 3-DES.

  3. «pkcs12», стандартный формат (OpenSSL может его прочитать), с несколькими вариантами, но обычно 3-DES для закрытых ключей и RC2-40 для сертификатов.

Во всех трех случаях частные данные зашифрованы (симметрично, с использованием индивидуальных паролей), а целостность всего хранилища ключей защищена криптографическим дайджестом (с использованием пароля хранилища ключей).

person Thilo    schedule 23.12.2009
comment
Проголосовал за, но также добавил более подробный / подробный ответ, возможно, вам будет интересно. - person Maarten Bodewes; 05.03.2021

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