Как добавить цепочку сертификатов в JKS

У меня есть цепочка сертификатов под названием: cert.cer с содержанием:

subject= ... OU=MyCA
issuer= ... OU=MyCA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

subject= ... OU=Client
issuer= .. OU=MyCA
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Я попытался добавить эту цепочку в JKS, позвонив:

keytool -import -trustcacerts -file cert.cer -keystore sample.keystore -storepass 123456 -alias chain

, который добавляет только сертификат верхнего уровня OU=MyCA.

Как правильно добавить эту цепочку в JavaKeyStore (JKS)?

2 ответа

Решение

Хорошо, я выполнил вашу команду для объединения сертификатов в формате PKCS7:

openssl > crl2pkcs7 -nocrl -certfile a.crt -certfile b.crt -out outfile.p7b

Это сработало.
Затем я попытался импортировать файл PKCS#7 в файл JKS, используя следующую команду:

keytool -import -trustcacerts -file outfile.p7b -keystore keystore1.jks -storepass 123456 -alias chain

Это не работает.
Затем я немного исследовал и обнаружил, что мне нужна цепочка сертификатов в файле либо в формате Base64, либо в формате Der. У меня был файл формата Base64. Итак, я попытался объединить файл, используя следующую команду Windows:

copy /b a.crt+b.crt c.crt

Команда Linux будет:

cat a.crt b.crt > c.crt

Итак, выходной файл выглядел так:

-----BEGIN CERTIFICATE-----
..............................
..............................
-----END CERTIFICATE----------BEGIN CERTIFICATE-----
...............................
...............................
-----END CERTIFICATE-----

Затем попытался импортировать цепочку сертификатов в JKS, используя приведенную выше команду. Это сработало. Затем я пытаюсь увидеть список сертификатов из хранилища ключей. Для этого я выполнил следующую команду:

keytool -list -v -keystore keystore1.jks

Но он сказал: "Только 1 запись найдена" и один сертификат был показан. Поскольку хранилище ключей не было загружено с полной цепочкой сертификатов, эксперимент не удался.
Итак, я попытался преобразовать файл PKCS#7 в цепочке сертификатов с помощью следующей команды openssl:

pkcs7 -print_certs -in outfile.p7b -out certificates.cer

Выходной файл выглядит точно так же, как у вас, начинается с темы dn и эмитента dn, а затем заголовка и нижнего колонтитула. Затем я попытался сохранить сертификаты из файла Certificates.cer в jks-файле keystore1.jks. Но, опять же, после импорта, это показывает, что хранилище ключей имеет только один сертификат. Итак, эмитент dn и тема dn не были проблемой.
Затем я попытался преобразовать файл Base64 в файл Der, а затем попытался объединить данные:

openssl x509 -in a.crt -outform DER -out aa.crt
openssl x509 -in b.crt -outform DER -out bb.crt
copy /b aa.crt+bb.crt cc.crt

Затем я попытался импортировать файл конкатерации в JKS. Но снова только один сертификат был импортирован.

Я действительно подумала о том, что действительно могу сделать неправильно. Итак, я искал исходный код KeyTool и нашел метод, в который импортировался сертификат или цепочка сертификатов.

Imports a JDK 1.1-style identity database. We can only store one certificate per identity, because we use the identity's name as the alias (which references a keystore entry), and aliases must be unique.

И я удивлен тем, что их код преобразует входной поток в список сертификатов, но они работают только с одним сертификатом сертификата (первым).

if (certs!=null && certs.length>0) {
      // we can only store one user cert per identity.
      // convert old-style to new-style cert via the encoding
         DerOutputStream dos = new DerOutputStream()
         certs[0].encode(dos);
         .............................

Поэтому мы ничего не можем сделать, чтобы добавить несколько сертификатов одновременно. Там политика один сертификат на одну запись. Итак, если у вас есть несколько сертификатов для входа, вы должны сделать запись их индивидуально. Или напишите немного кода Java, чтобы облегчить нашу работу (я всегда так делаю).
Извините, что сделал это так долго. Но, надеюсь, это очистит большую часть вашего замешательства.

Существует два вида записей в хранилище ключей JKS-типа:

  • запись PrivateKey содержит приватный ключ и сертификат или цепочку сертификатов для этого приватного ключа

  • запись TrustedCert содержит ровно один сертификат и не имеет закрытого ключа

Общий интерфейс KeyStore допускает третий тип записи для SecretKey, но он не поддерживается JKS, только гораздо менее используемый JCEKS, и я считаю, что формат BouncyCastle.

Я нашел ваш другой вопрос https://security.stackexchange.com/questions/95945/how-to-add-a-certificate-chain-to-a-jks котором объясняется, почему вы не хотите, чтобы запись закрытого ключа была правильной. Однако большинство инструкций, которые вы найдете для keytool и т. Д., Касаются присоединения цепочки (обычно возвращаемой из ЦС) к приватному ключу и скрывают тот факт, что вы не можете хранить цепочку сертификатов как одну запись без приватного ключа.

Так что да, вы должны ввести каждый сертификат отдельно. Однако это не обязательно означает, что вы должны получать каждый сертификат отдельно. CertPathBuilder существует именно для извлечения из хранилища доверенных сертификатов, такого как (но не только), JKS всех сертификатов, образующих допустимую цепочку. К сожалению, навороты, необходимые для правильной работы CertPathBuilder (и, в частности, "PKIX") для SSL/TLS, делают его довольно неуклюжим для использования в более простых приложениях, поэтому вы можете предпочесть просто получить сертификаты.

PEM-сцепленные PEM-сертификаты работают там, где разрешена цепочка (только с приватным ключом), но приведенный вами пример недопустим. -----BEGIN а также -----END линии должны быть отдельными линиями, а НЕ бегать вместе, как у вас.

Другие вопросы по тегам