Преобразование хранилища ключей Java в формат PEM

132

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

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

Но предпочтительнее прямой метод конвертации из jks в pem.

Чатуранга Чандрасекара
источник

Ответы:

214

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

bash $ keytool -keystore foo.jks -genkeypair -alias foo \
        -dname 'CN = foo.example.com, L = Мельбурн, ST = Виктория, C = AU'
Введите пароль хранилища ключей:  
Повторно введите новый пароль: 
Введите ключевой пароль для 
        (ВОЗВРАТ если совпадает с паролем хранилища ключей):  
bash $ keytool -keystore foo.jks -exportcert -alias foo | \
       openssl x509 -inform der -text
Введите пароль хранилища ключей: asdasd
Сертификат:
    Данные:
        Версия: 3 (0x2)
        Серийный номер: 1237334757 (0x49c03ae5)
        Алгоритм подписи: dsaWithSHA1
        Эмитент: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        Срок действия
            Не раньше: 18 марта, 00:05:57 2009 г., GMT
            Не после: 16 июня, 00:05:57 2009 г., GMT
        Тема: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        Информация об открытом ключе субъекта:
            Алгоритм открытого ключа: dsaEncryption
            Открытый ключ DSA:
                паб: 
                    00: е2: 66: 5с: е0: 2e: да: е0: 6b: а6: аа: 97: 64: 59: 14:
                    7e: а6: 2e: 5а: 45: f9: 2f: В5: 2d: f4: 34: 27: е6: 53: с7:
 

bash $ keytool -importkeystore -srckeystore foo.jks \
       -destkeystore foo.p12 \
       -srcstoretype jks \
       -deststoretype pkcs12
Введите пароль целевого хранилища ключей:  
Повторно введите новый пароль: 
Введите пароль исходного хранилища ключей:  
Запись для псевдонима foo успешно импортирована.
Команда импорта выполнена: 1 запись успешно импортирована, 0 записей не выполнено или отменено

bash $ openssl pkcs12 -in foo.p12 -out foo.pem
Введите пароль для импорта:
MAC подтвержден ОК
Введите парольную фразу PEM:
Проверка - введите парольную фразу PEM:

bash $ openssl x509 -text -in foo.pem
Сертификат:
    Данные:
        Версия: 3 (0x2)
        Серийный номер: 1237334757 (0x49c03ae5)
        Алгоритм подписи: dsaWithSHA1
        Эмитент: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        Срок действия
            Не раньше: 18 марта, 00:05:57 2009 г., GMT
            Не после: 16 июня, 00:05:57 2009 г., GMT
        Тема: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        Информация об открытом ключе субъекта:
            Алгоритм открытого ключа: dsaEncryption
            Открытый ключ DSA:
                паб: 
                    00: е2: 66: 5с: е0: 2e: да: е0: 6b: а6: аа: 97: 64: 59: 14:
                    7e: а6: 2e: 5а: 45: f9: 2f: В5: 2d: f4: 34: 27: е6: 53: с7:
 

bash $ openssl dsa -text -in foo.pem
прочитать ключ DSA
Введите парольную фразу PEM:
Закрытый ключ: (1024 бит)
собств:
    00: 8f: b1: аф: 55: 63: 92: 7в: d2: 0f: е6: f3: а2: f5: FF:
    1a: 7a: Fe: 8c: 39: дд
паб: 
    00: е2: 66: 5с: е0: 2e: да: е0: 6b: а6: аа: 97: 64: 59: 14:
    7e: а6: 2e: 5а: 45: f9: 2f: В5: 2d: f4: 34: 27: е6: 53: с7:



В итоге вы получите:

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

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


Сводка команд - для создания хранилища ключей JKS:

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

Сводка команд - для преобразования хранилища ключей 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

Сводка команд - для сравнения хранилища ключей 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
Stobor
источник
12
Доверенные сертификаты не поддерживаются в этом методе: это ограничение формата PKS12, которое, как мне кажется, см .: java.sun.com/javase/6/docs/technotes/guides/security/jsse/… (раздел о java.security.KeyStoreException : TrustedCertEntry не поддерживается)
andygavin
2
У меня есть более старый файл JKS. Я не смог экспортировать, используя метод выше. Я наконец смог это сделать, установив для аргумента keytool '-destkeypass' фиктивное значение. 'keytool' даже выводит предупреждение о том, что он игнорирует значение destkeypass? Никакая другая техника не сработает. Использование подсказок не помогло, работает только с аргументом командной строки. Должна быть ошибка в экспорте PKCS12, кто-нибудь может прокомментировать?
cmcginty
4
"openssl pkcs12 -in foo.p12 -out foo.pem" выдает следующую ошибку. Введите пароль для импорта: MAC проверен OK. Ошибка вывода ключей и сертификатов. 139848775526048: ошибка: 06065064: подпрограммы цифрового конверта: EVP_DecryptFinal_ex: плохое расшифровывание: evp_enc.c: 539. : 139848775526048: ошибка: 23077074: подпрограммы PKCS12: PKCS12_pbe_crypt: pkcs12 cipherfinal error: p12_decr.c: 104: 139848775526048: ошибка: 2306A075: подпрограммы PKCS12: PKCS12_item_decryptr. Какое решение для этого?
Udara SS Liyanage
1
предупреждение для других, команда keytool по какой-то причине требует времени для выполнения, мне пришлось ждать 30 секунд, пока экспорт не был завершен
Николас Моммартс,
1
@ UdaraS.SLiyanage: посмотрите на ответ Кейси, чтобы
найти
29

Я все время получал ошибки 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 будет работать только этот стиль команды

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

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

cmcginty
источник
6
Обоснование можно найти здесь: herongyang.com/PKI/… Destkeypass ДЕЙСТВИТЕЛЬНО имеет значение, кстати,
Николас Моммартс,
Я проголосовал за этот комментарий, но он заслуживает отдельной публикации. Здесь было сложно найти.
Ричи Рич
15

Команда 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
Эриксон
источник
Спасибо, erickson .. Вывод такой: «Мы не можем выполнить прямое преобразование из JKS в PEM, просто используя утилиты keytool и openssl». Я прав?
Чатуранга Чандрасекара,
4
Вам нужно только написать код до Java 1.4 - начиная с Java 5, keytool и openssl могут быть объединены для выполнения двухэтапного преобразования из JKS -> PKCS # 12 -> PEM. Однако написание собственного ключевого инструмента - единственный способ выполнить ПРЯМОЕ ПРЕОБРАЗОВАНИЕ из JKS -> PEM.
Стобор, 04
Я думаю, что это начиная с JDK 6 и далее. Но да, теперь поддерживается импорт PKCS # 12.
erickson
13

Прямое преобразование из jks в файл pem с помощью keytool

keytool -exportcert -alias selfsigned -keypass password -keystore test-user.jks -rfc -file test-user.pem
sanghaviss
источник
10
Да, это экспортирует сертификат. Однако он не экспортирует ключевую информацию ...
Стобор,
Это точный простой ответ на то, что я безуспешно искал на десятках keytoolи jbossстраницах документации. Спасибо!
Кратенко
15
ЭТО НЕ ЭКСПОРТ КЛЮЧЕВОЙ ЛИЧНОЙ ИНФОРМАЦИИ
Джеймс,
1
Это экспортирует сертификат открытого ключа
asami
Я пробовал запустить эту команду. Требуется пароль. Введите пароль хранилища ключей: ошибка keytool: java.io.IOException: хранилище ключей было подделано или пароль был неверным. Я использовал пароль в качестве (пароля), но он
Мохит Сингх
9

Упрощенные инструкции по преобразованию файла JKS в формат PEM и KEY (.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>
Асы
источник
2

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

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

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

Марко Лули
источник
2

Преобразование 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"перечисляет все в хранилище ключей myKeyStore.jks в формате PEM. Однако он также печатает дополнительную информацию.
  2. | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d"отфильтровывает все, что нам не нужно. У нас остались только PEM всего в KeyStore.
  3. >> "myKeystore.pem" запишите PEM в файл myKeyStore.pem.
Марк Лагендейк
источник
3
bash:! d ": событие не найдено
user3217883
1
@ user3217883 Вместо этого вы можете попробовать что-то вроде sed "s/^\-*BEGIN [A-Z]*\-*$//g;s/^\-*END [A-Z]*\-*$//g"(с gnu sed), но я не уверен, что этого достаточно, если в вашем хранилище ключей больше одного сертификата
Идрисс Нойманн
если вы получаете bash: !d": event not found: для bash восклицательный знак - это короткий ключ для использования команды. Чтобы использовать этот ответ, вам нужно использовать апострофы вместо кавычек для параметра, используемого как -e для sedkeytool -list -rfc -keystore "myKeystore.jks" | sed -e '/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d' >> "myKeystore.pem"
Б. Адлер
К сожалению, экспортируется только сертификат, а не закрытый ключ
Maddin
2

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

1. keytool -importkeystore -srckeystore ~ ​​/ .android / debug.keystore -destkeystore intermediate.p12 -srcstoretype JKS -deststoretype PKCS12

Выгрузите новый файл pkcs12 в pem

  1. openssl pkcs12 -in intermediate.p12 -nodes -out Intermediate.rsa.pem

У вас должен быть сертификат и закрытый ключ в формате pem. Разделите их. Поместите часть между «BEGIN CERTIFICATE» и «END CERTIFICATE» в cert.x509.pem. Поместите часть между «BEGIN RSA PRIVATE KEY» и «END RSA PRIVATE KEY» в private.rsa.pem. Преобразуйте закрытый ключ в формат pk8 как ожидается сигналом

3. openssl pkcs8 -topk8 -outform DER -in private.rsa.pem -inform PEM -out private.pk8 -nocrypt

nkalra0123
источник
1

Что ж, OpenSSL должен делать это легко из файла №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

Может быть, поподробнее, что это за ошибка / сбой?

Чарли Мартин
источник
1

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

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

  1. Откройте хранилище ключей JKS
  2. Щелкните правой кнопкой мыши по записи закрытого ключа и выберите экспорт.
  3. Выберите закрытый ключ и сертификаты и формат PEM

    Экспорт закрытого ключа PEM из JKS с помощью Portcle

Марсио Ясински
источник
0

Попробуйте Keystore Explorer http://keystore-explorer.org/

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

Johnny Boy
источник
0

сначала создайте файл хранилища ключей как

C: \ Program Files \ Android \ Android Studio \ jre \ bin> keytool -keystore androidkey.jks -genkeypair -alias androidkey

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

Теперь он попросит подтвердить

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

Введите ключевой пароль для (ВОЗВРАТ, если такой же, как пароль хранилища ключей): нажмите Enter, если вы хотите тот же пароль

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

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

Анкит Дубей
источник
0

Преобразование хранилища ключей Java в формат PEM

Самый точный ответ должен заключаться в том, что это НЕ возможно.

Хранилище ключей Java - это просто средство хранения криптографических ключей и сертификатов, в то время как PEM - это формат файла только для сертификатов X.509.

whaefelinger
источник