2009-03-17 6 views
107

Я пытаюсь преобразовать из файла хранилища ключей Java в файл PEM с помощью приложений keytool и openssl. Но я не мог найти хороший способ сделать конверсию. Есть идеи?Преобразование Java Keystore в формат PEM

Вместо преобразования хранилища ключей непосредственно в PEM я попытался сначала создать файл PKCS12, а затем преобразовать в соответствующий файл PEM и Keystore. Но я не мог установить соединение, используя их. (Обратите внимание, что мне просто нужен файл PEM и файл Keystore для реализации защищенного соединения. Нет никаких ограничений, таких как «Начать с файла хранилища Java». :) Так что, начиная с других форматов, допустимо с моим футляром)

Но предпочтительным является метод прямого преобразования от jks до pem.

ответ

182

Это довольно просто, используя JDK6 по крайней мере ...

 
bash$ keytool -keystore foo.jks -genkeypair -alias foo \ 
     -dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU' 
Enter keystore password: 
Re-enter new password: 
Enter key password for 
     (RETURN if same as keystore password): 
bash$ keytool -keystore foo.jks -exportcert -alias foo | \ 
     openssl x509 -inform der -text 
Enter keystore password: asdasd 
Certificate: 
    Data: 
     Version: 3 (0x2) 
     Serial Number: 1237334757 (0x49c03ae5) 
     Signature Algorithm: dsaWithSHA1 
     Issuer: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com 
     Validity 
      Not Before: Mar 18 00:05:57 2009 GMT 
      Not After : Jun 16 00:05:57 2009 GMT 
     Subject: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com 
     Subject Public Key Info: 
      Public Key Algorithm: dsaEncryption 
      DSA Public Key: 
       pub: 
        00:e2:66:5c:e0:2e:da:e0:6b:a6:aa:97:64:59:14: 
        7e:a6:2e:5a:45:f9:2f:b5:2d:f4:34:27:e6:53:c7: 
    

bash$ keytool -importkeystore -srckeystore foo.jks \ 
     -destkeystore foo.p12 \ 
     -srcstoretype jks \ 
     -deststoretype pkcs12 
Enter destination keystore password: 
Re-enter new password: 
Enter source keystore password: 
Entry for alias foo successfully imported. 
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled 

bash$ openssl pkcs12 -in foo.p12 -out foo.pem 
Enter Import Password: 
MAC verified OK 
Enter PEM pass phrase: 
Verifying - Enter PEM pass phrase: 

bash$ openssl x509 -text -in foo.pem 
Certificate: 
    Data: 
     Version: 3 (0x2) 
     Serial Number: 1237334757 (0x49c03ae5) 
     Signature Algorithm: dsaWithSHA1 
     Issuer: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com 
     Validity 
      Not Before: Mar 18 00:05:57 2009 GMT 
      Not After : Jun 16 00:05:57 2009 GMT 
     Subject: C=AU, ST=Victoria, L=Melbourne, CN=foo.example.com 
     Subject Public Key Info: 
      Public Key Algorithm: dsaEncryption 
      DSA Public Key: 
       pub: 
        00:e2:66:5c:e0:2e:da:e0:6b:a6:aa:97:64:59:14: 
        7e:a6:2e:5a:45:f9:2f:b5:2d:f4:34:27:e6:53:c7: 
    

bash$ openssl dsa -text -in foo.pem 
read DSA key 
Enter PEM pass phrase: 
Private-Key: (1024 bit) 
priv: 
    00:8f:b1:af:55:63:92:7c:d2:0f:e6:f3:a2:f5:ff: 
    1a:7a:fe:8c:39:dd 
pub: 
    00:e2:66:5c:e0:2e:da:e0:6b:a6:aa:97:64:59:14: 
    7e:a6:2e:5a:45:f9:2f:b5:2d:f4:34:27:e6:53:c7: 



Вы в конечном итоге с:

  • foo.jks - хранилище ключей в формате Java.
  • foo.p12 - keystore в формате PKCS # 12.
  • foo.pem - все ключи и сертификаты из хранилища ключей, в формате PEM.

(Этот последний файл можно разделить на ключи и сертификаты, если хотите.)


резюме Command - создать JKS хранилище ключей:

keytool -keystore foo.jks -genkeypair -alias foo \ 
    -dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU' 

сводной Command - конвертировать JKS хранилищу в PKCS # 12 хранилища ключей, а затем в PEM файл:

keytool -importkeystore -srckeystore foo.jks \ 
    -destkeystore foo.p12 \ 
    -srcstoretype jks \ 
    -deststoretype pkcs12 

openssl pkcs12 -in foo.p12 -out foo.pem 

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

keytool -importkeystore -srckeystore foo.jks \ 
    -destkeystore foo.p12 \ 
    -srcalias foo \ 
    -srcstoretype jks \ 
    -deststoretype pkcs12 

openssl pkcs12 -in foo.p12 -out foo.pem 

резюме Command - сравнить JKS хранилище ключей PEM файл:

keytool -keystore foo.jks -exportcert -alias foo | \ 
    openssl x509 -inform der -text 

openssl x509 -text -in foo.pem 

openssl dsa -text -in foo.pem 
+12

Надежные сертификаты в этом методе не поддерживаются: это ограничение формата PKS12, которое, я считаю, см .: http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html# InstallProbs (раздел о java.security.KeyStoreException: TrustedCertEntry не поддерживается) – andygavin

+0

@andygavin: Действительно; это правда. Хотя формат PKCS может содержать произвольно множество сертификатов, у него нет поля, указывающего, является ли сертификат доверенным или нет. Однако вопрос состоял в том, как в конечном итоге получить файл PEM (PKCS # 7), который также не имеет этой информации доверия, поэтому это не проблема процесса ... – Stobor

+0

, который должен читать «... while формат PKCS # 12 ... " – Stobor

1

Ну, OpenSSL should do it handily из # 12 файла в:

openssl pkcs12 -in pkcs-12-certificate-file -out pem-certificate-file 
openssl pkcs12 -in pkcs-12-certificate-and-key-file -out pem-certificate-and-key-file 

Возможно больше подробностей о том, что ошибка/отказ?

13

Команда keytool не позволит вам экспортировать закрытый ключ из хранилища ключей. Для этого вам нужно написать код Java. Откройте хранилище ключей, получите необходимый ключ и сохраните его в файле в формате PKCS # 8. Сохраните соответствующий сертификат.

KeyStore ks = KeyStore.getInstance("jks"); 
/* Load the key store. */ 
... 
char[] password = ...; 
/* Save the private key. */ 
FileOutputStream kos = new FileOutputStream("tmpkey.der"); 
Key pvt = ks.getKey("your_alias", password); 
kos.write(pvt.getEncoded()); 
kos.flush(); 
kos.close(); 
/* Save the certificate. */ 
FileOutputStream cos = new FileOutputStream("tmpcert.der"); 
Certificate pub = ks.getCertificate("your_alias"); 
cos.write(pub.getEncoded()); 
cos.flush(); 
cos.close(); 

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

openssl pkcs8 -inform der -nocrypt <tmpkey.der> tmpkey.pem 
openssl x509 -inform der <tmpcert.der> tmpcert.pem 
+0

Спасибо erickson. Вывод: «Мы не можем выполнить прямое преобразование из JKS в PEM, просто используя утилиты keytool и openssl». Я прав? –

+4

Вы только __need__, чтобы написать код до Java 1.4 - начиная с Java 5, keytool и openssl могут быть объединены для выполнения двухэтапного преобразования из JKS -> PKCS # 12 -> PEM. Однако написать свой собственный ключевой инструмент - единственный способ выполнить __DIRECT CONVERSION__ от JKS -> PEM. – Stobor

+0

Я думаю, что это от JDK 6 дальше. Но да, теперь поддерживается импорт PKCS # 12. – erickson

12

прямого преобразования из JKS в PEM файл, используя Keytool

keytool -exportcert -alias selfsigned -keypass password -keystore test-user.jks -rfc -file test-user.pem 
+9

Да, это экспортирует сертификат. Однако он не экспортирует ключевую информацию ... – Stobor

+0

Это точный простой ответ на то, что я искал на десятках страниц «keytool» и 'jboss' doc без успеха. Благодаря! – kratenko

+10

ЭТО НЕ ЭКСПОРТ ЧАСТНАЯ ИНФОРМАЦИЯ КЛЮЧА – James

2

Я нашел очень интересное решение:

http://www.swview.org/node/191

Затем я разделил открытый/закрытый ключ пары на два файла private.key publi.pem, и он работает!

25

я продолжал получать ошибки из openssl при использовании команды StoBor в:

MAC verified OK 
Error outputting keys and certificates 
139940235364168:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:535: 
139940235364168:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:97: 
139940235364168:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:123: 

По какой-то причине, только этот стиль команды будет работать для моего JKS файла

Ключ садился destkeypass, значение аргумента не имело значения.

+5

Обоснование можно найти здесь: http://www.herongyang.com/PKI/Intermediate-CA-OpenSSL-pkcs12-Decrypt-Error.html destkeypass DOES matter btw –

+0

Я одобрил этот комментарий, но он заслуживает своего собственного сообщения. Трудно было найти здесь. –

+0

Вы спасли мою жизнь от ∞ потерянных часов! –

5

упрощенная инструкция преобразует JKS файл в PEM и формат ключ (.crt & .key):

keytool -importkeystore -srckeystore <Source-Java-Key-Store-File> -destkeystore <Destination-Pkcs12-File> -srcstoretype jks -deststoretype pkcs12 -destkeypass <Destination-Key-Password> 

openssl pkcs12 -in <Destination-Pkcs12-File> -out <Destination-Pem-File> 

openssl x509 -outform der -in <Destination-Pem-File> -out <Destination-Crt-File> 

openssl rsa -in <Destination-Pem-File> -out <Destination-Key-File> 
1

Преобразования JKS KeyStore в один файл PEM может быть легко достигнут с помощью следующей команды:

keytool -list -rfc -keystore "myKeystore.jks" | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d" >> "myKeystore.pem" 

Пояснение:

  1. keytool -list -rfc -keystore "myKeystore.jks" списки everythin g в ключевом хранилище myKeyStore.jks в формате PEM. Однако он также печатает дополнительную информацию.
  2. | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d" отфильтровывает все, что нам не нужно. У нас остались только PEM всего в KeyStore.
  3. >> "myKeystore.pem" пишите ПЭМ в файл 'myKeyStore.pem'.
+0

bash:! D ": событие не найдено – user3217883

+0

@ user3217883 Вы можете попробовать что-то вроде' sed 's/^ \ - * BEGIN [AZ] * \ - * $ // g; s/^ \ - * END [AZ] * \ - * $ // g "вместо этого (с gnu sed), но я не уверен, что этого достаточно, если в вашем хранилище ключей есть несколько сертификатов. –

1

Если у вас нет установленного устройства openssl, и вы ищете быстрое решение, есть программное обеспечение под названием portcle, которое очень полезно и мало для загрузки.

Недостатком является то, что нет никакой командной строки, насколько я знаю. Но из графического интерфейса, это довольно прямо вперед, чтобы экспортировать PEM закрытый ключ:

  1. Открыть вы JKS хранилище ключей
  2. правой кнопкой на ваш личный ключ и выбрать экспорт
  3. Select Private Key и сертификаты и формат PEM

    Export PEM private key from JKS with Portcle

+0

Работал для меня. – star

0

Попробуйте Keystore Проводник http://keystore-explorer.org/

KeyStore Explorer - это замена графического интерфейса с открытым исходным кодом для инструментов командной строки для командной строки Java keytool и jarsigner. Он также открывает/pkcs12.

0

сначала создать файл хранилищу, как

C: \ Program Files \ Android \ Android Студия \ JRE \ Bin>Keytool -keystore androidkey.jks -genkeypair -alias androidkey

Введите пароль для хранилища ключей:
Введите новый пароль:
Ваше имя и фамилия? Неизвестно: FirstName LastName
Как называется ваше подразделение? Неизвестный: Мобильная разработка
Как вы называете организацию? Неизвестно: название вашей компании
Как зовут ваш город или местность? Как называется ваше государство или провинция?
Что такое двухбуквенный код страны для данного устройства? Неизвестный: В // Пресс ввести

Now it will ask to confirm

Является ли CN = LastName FirstName, OU = Mobile Development, O = название вашей компании, L = CityName, ST = StateName, C = IN правильно? [нет]: да

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

key has been generated, now you can simply get pem file using following command

C: \ Program Files \ Android \ Android-студия \ JRE \ Bin>Keytool -export -rfc -alias androidkey -file android_certificate.pem -keystore androidkey.jks
Введите пароль для хранилища ключей:
сертификат, хранящийся в файле