добавление приватного ключа в хранилище ключей - PullRequest
0 голосов
/ 29 мая 2018

В связи с обновлением некоторых сертификатов мне пришлось преобразовать хранилище ключей jks в хранилище ключей PKCS # 12 и включить закрытый ключ во время преобразования.Мы получили хранилище ключей как хранилище ключей JKS, однако наши веб-серверы используют хранилища ключей PKCS # 12, а полученные нами хранилища ключей содержали только сертификаты, а не закрытый ключ.

Я попытался погуглить и просмотреть несколько записей в SO, и я только нашел решение, которое больше похоже на обходной путь, чем на хороший подход, поэтому мне было интересно, есть ли у кого-то лучшеПодход к тому, как внедрить закрытые ключи и преобразовать из хранилища ключей jks в хранилище ключей PKCS # 12 более простым способом.

Кажется, что хранилищами ключей JKS можно манипулировать только с помощью keytool, однако утилита keytool не поддерживает инъекциюзакрытых ключей в AFDIK доверенного сервера, так что я использовал следующий подход:

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

  1. извлек все сертификаты из хранилища ключей jks с помощьюKeytool.
  2. создал хранилище ключей PKCS # 12, используя openssl
  3. , переименуйте псевдоним в созданном PKCS12, используя keytool
  4. , создайте другое хранилище ключей PKCS # 12, используя openssl
  5. , объедините два хранилища ключей в один, используя keytool
  6. , импортируя сертификаты без закрытых ключей

Таквесь процесс выглядит следующим образом (в случае, если это также необходимо):

openssl pkcs12 -in orig.alias.p12 -nodes -nocerts -out key.pem -passin pass:PASSWORD
keytool -keystore keystore1 -storepass PASSWORD -list
keytool -keystore keystore1 -storepass PASSWORD -rfc -file alias.root.pem -alias "root" -exportcert
keytool -keystore keystore1 -storepass PASSWORD -rfc -file alias.ca3.pem -alias "ca3" -exportcert
keytool -keystore keystore1 -storepass PASSWORD -rfc -file alias.long.pem -alias "long" -exportcert
keytool -keystore keystore1 -storepass PASSWORD -rfc -file alias.short.pem -alias "short" -exportcert
openssl pkcs12 -export -out keystore.p12 -inkey key.pem -in alias.short.pem -passout pass:PASSWORD
keytool -changealias -alias "1" -destalias "short" -keypass PASSWORD -keystore keystore.p12 -storepass PASSWORD
openssl pkcs12 -export -out keystore2.p12 -inkey key.pem -in alias.long.pem -passout pass:PASSWORD
keytool -changealias -alias "1" -destalias "long" -keypass PASSWORD -keystore keystore2.p12 -storepass PASSWORD
keytool -importkeystore -srckeystore keystore2.p12 -srcstoretype pkcs12 -srcstorepass PASSWORD -destkeystore keystore.p12 -deststoretype pkcs12 -deststorepass PASSWORD
keytool -keystore keystore.p12 -storepass PASSWORD -file alias.ca3.pem -alias "ca3" -importcert -noprompt
keytool -keystore keystore.p12 -storepass PASSWORD -file alias.root.pem -alias "root" -importcert  -noprompt
keytool -keystore keystore.p12 -storepass PASSWORD -list

Я представлял себе, например, если бы я мог установить псевдоним при импорте сертификата с закрытым ключом, тогда мне не нужно было бы впоследствии переименовывать псевдоним.Это возможно?

В любом случае, заранее спасибо

1 Ответ

0 голосов
/ 29 мая 2018
  1. Вы можете исключить шаги -changealias, используя -name long и -name short на шагах pkcs12 -export

  2. Для keystore.p12 иkeystore2.p12 ваши входные данные key.pem и (сертификат) alias.short.pem.Вы намеревались использовать (cert) alias.long.pem для одного из них?

  3. Среди бесплатных Oracle Javas только более поздние версии j8 (с keystore.compat, установленным в java.security) могутчитать оба JKS и P12 хранилища ключей без указания типа.По умолчанию j7 и ниже делают только JKS, j9 и выше только P12.

  4. FWIW, если вы конвертируете исходный JKS (с доверенным сертификатом) в P12 (только с j8 +), тогда openssl pkcs12 -nokeysвыведет все доверенные сертификаты за одну операцию - но, поскольку вам нужно делать с ними разные вещи, вам нужно разделить их на отдельные файлы или сделать по требованию, например:

    awk '/friendlyName: short/,/-END CERT/' allcerts.pem | \
      openssl pkcs12 -export -inkey key.pem -name short -out file -passout pass:PW
    # similar for long -- or make loop
    # combine the p12s as before
    awk '/friendlyName: root/,/-END CERT/' allcerts.pem | \
      keytool -keystore file -storepass PW -importcert -file root.pem -alias root -noprompt
    # similar for ca3 -- or make loop

... но я не уверен, что это действительно улучшение

В качестве альтернативы, поскольку это ТАК, вы могли бы написать программу, которая делает это более напрямую:

char[] pw = "PASSWORD".toCharArray(); // or whatever as appropriate
KeyStore ks1 = KeyStore.getInstance("JKS"); ks1.load (new FileInputStream ("certs",pw));
KeyStore ks2 = KeyStore.getInstance("PKCS12"); 
try( InputStream is = new FileInputStream("oldp12") ){ ks2.load(is,pw); }
String alias = ks2.getAliases().nextElement(); // assume only one
PrivateKey key = (PrivateKey) ks2.getKey(alias,pw); 
ks2.deleteAlias(alias); 
ks2.setKeyEntry("short",key,pw,new Certificate[]{ ks1.getCertificate("short") });
ks2.setKeyEntry("long" ,key,pw,new Certificate[]{ ks1.getCertificate("long" ) });
// assuming those combinations are what you intended, see above
ks2.setCertificateEntry("root", ks1.getCertificate("root") );
ks2.setCertificateEntry("ca3" , ks1.getCertificate("ca3" ) );
try( OutputStream os = new FileOutputStream ("newp12") ){ ks2.store(os,pw); }
...