Защищенное паролем хранилище доверенных сертификатов, созданное с помощью keytool, не отображает никаких записей, если не указан пароль

Я борюсь с различием в поведении между способом, которым keytool создает хранилище ключей (используется здесь как хранилище доверенных сертификатов) и импортирует доверенный сертификат, VS, как другие инструменты (например, portecle, kse) сделайте то же самое .

Рассмотрим эту команду:

keytool -import -alias myAlias -file ./my_exported_server_cert.crt \
-keystore ./my_truststore.jks

Мне будет предложено ввести пароль, а затем создать my_truststore.jks, содержащий сертификат.

Теперь, если я загляну внутрь и введу правильный пароль, появится запись myAlias:

keytool -v -list -keystore ./my_truststore.jks -storeType jks -storepass myPass

или программно ...

try (InputStream is = new FileInputStream(new File("./my_truststore.jks"))) {
    KeyStore keyStore = KeyStore.getInstance("jks");
    keyStore.load(is, "myPassword".toCharArray());
    Iterator<String> it = keyStore.aliases().asIterator();
    while (it.hasNext()) System.out.println(it.next());
}

Однако, если я не предоставляю пароль (т. Е. Удаляю параметр storepass из вызова keytool и набираю return при появлении запроса, или вызываю load с null в качестве второго аргумента в коде Java), записи не будут перечисленные.

keytool выводит предупреждение, но не содержит записей.

Теперь, если я создаю хранилище доверенных сертификатов и импортирую сертификат таким же образом с помощью portecle или kse, устанавливаю пароль и снова запускаю проверки без ввода пароля, myAlias по-прежнему отображается как запись (keytool отображает предупреждение, как ожидалось, но также отображает сертификат).

Мое спорное понимание этого вопроса состоит в том, что пароль менее важен для чтения содержимого доверенного хранилища (без особого исследования я также предполагаю, что именно поэтому TrustManagerFactory # init не принимает пароль, в отличие от KeyManagerFactory # init).

Мой вопрос

  • В чем причина разницы в поведении? Разве эти инструменты не используют те же основные API-интерфейсы, что и keytool за кулисами?
  • Есть ли способ параметризовать keytool, чтобы создать хранилище доверенных сертификатов, которое позволяет просматривать записи при запросе без пароля, как это делают другие инструменты?

Примечания

Я воспроизвел это поведение с keytool из:

  • Oracle JDK 11
  • Oracle JDK 12
  • OpenJDK11

При тестировании с keytool из Oracle JDK8 я замечаю, что запись найдена, хотя я получаю предупреждения при первоначальном создании хранилища ключей на стороне сервера, а также при экспорте одного сертификата:

Хранилище ключей JKS использует собственный формат. Рекомендуется перейти на PKCS12, который является отраслевым стандартным форматом, используя "keytool -importkeystore -srckeystore ./ora8_keystore.jks -destkeystore ./ora8_keystore.jks -deststoretype pkcs12"

Более того, квитирование SSL с использованием хранилища доверенных сертификатов, созданного с помощью keytool из Oracle JDK8, кажется, просто зависает навсегда без каких-либо следов сбоя.

Во время отладки своего Java-кода я заметил, что доверенные хранилища, созданные любым инструментом и JDK (включая Oracle JDK8), в конечном итоге были инициализированы фабрикой как хранилище ключей двойного формата независимо от используемого аргумента factory (jks), т. Е. Объект хранилища ключей имел class sun.security.provider.JavaKeyStore$DualFormatJKS, с spi, имеющим primaryType = JKS и secondaryType = PCKS12.

Этот последний момент не очень помогает мне понять, но он может иметь какое-то отношение.


person Mena    schedule 02.04.2019    source источник
comment
Это не мой опыт более 20 лет.   -  person user207421    schedule 02.04.2019
comment
@ user207421 это должно быть довольно просто воспроизвести. Вы пробовали конкретный сценарий?   -  person Mena    schedule 02.04.2019
comment
А я уже указывал, всем этим занимаюсь уже более 20 лет. Все, что вы получаете, если не предоставляете пароль, - это (1) невозможность доступа к закрытым ключам и (2) отсутствие проверки структуры хранилища ключей.   -  person user207421    schedule 03.04.2019
comment
@ user207421 вот как я ожидал, что это будет работать, да. И все же я могу реплицировать недостающую часть записи как с keytool list, так и программно, когда хранилище доверенных сертификатов было создано с помощью keytool, а сертификат импортирован с помощью keytool, по крайней мере, с java 11 и новее.   -  person Mena    schedule 03.04.2019
comment
У меня аналогичная проблема, дайте мне знать, если вы нашли ответ. Моя проблема в том, что в одном из хранилищ доверия не перечислены все сертификаты без пароля. Когда я указываю его с правильным паролем, он правильно отображает содержимое.   -  person Amit S    schedule 09.05.2019
comment
@AmitS, который действительно очень похож. К сожалению, у меня до сих пор нет подходящего решения для этого, хотя я подозреваю, что это изменение связано с более поздними версиями Oracle Java (и распространяется на openJDK). Мое обходное решение было следующим:   -  person Mena    schedule 09.05.2019
comment
@AmitS, поскольку мой контекст обычно интерактивен, я проверяю, выглядит ли хранилище доверенных сертификатов пустым, и, если да, предлагаю пользователю ввести пароль. Если после этого он по-прежнему кажется пустым, я могу сообщить пользователю, что либо пароль неверен, либо хранилище доверенных сертификатов действительно пусто.   -  person Mena    schedule 09.05.2019
comment
@AmitS, конечно, это не сработает, если каким-то образом будут видны только некоторые сертификаты - я еще не сталкивался с этим угловым случаем, но для меня это было бы немного катастрофой: S   -  person Mena    schedule 09.05.2019
comment
Спасибо @Mena за быстрый ответ. Я изо всех сил пытаюсь воспроизвести его с другими хранилищами доверенных сертификатов, я создал CSR на прошлой неделе, отправил запрос на сертификат, импортировал сгенерированный сертификат, и этот не перечисляет контент без пароля, но все предыдущие и новые открываются правильно.   -  person Amit S    schedule 09.05.2019
comment
@Mena Просто хотел обновить, моя проблема была связана с JDK10 (JKS был создан с его использованием) против JDK8 (версия Java по умолчанию, используемая на терминале для отображения KS). Если я использую JDK8 для создания и перечисления JKS, он работает нормально. Я фактически обновил JDK и JRE в своей среде IDE при создании проблемного JKS.   -  person Amit S    schedule 10.05.2019


Ответы (1)


Эту проблему лучше всего описать в открытой ошибке JDK https://bugs.openjdk.java.net/browse/JDK-8194702. У нас пока нет решения этой проблемы.

person Tarun Sharma    schedule 01.06.2021