Як імпортувати існуючий сертифікат X.509 та приватний ключ у сховищі Java для використання у SSL?


228

Я маю це в налаштуваннях ActiveMQ:

<sslContext>
        <sslContext keyStore="file:/home/alex/work/amq/broker.ks"  
 keyStorePassword="password" trustStore="file:${activemq.base}/conf/broker.ts" 
 trustStorePassword="password"/>
</sslContext>

У мене є пара X.509 cert та файл ключів.

Як імпортувати ці два, щоб використовувати їх у SSL та SSL + stomp роз'ємах? Усі приклади, з якими я міг би google, завжди генерував ключ, але ключ у мене вже є.

я намагався

keytool -import  -keystore ./broker.ks -file mycert.crt

але це імпортує лише сертифікат, а не ключовий файл і призводить до

2009-05-25 13:16:24,270 [localhost:61612] ERROR TransportConnector - Could not accept connection : No available certificate or key corresponds to the SSL cipher suites which are enabled.

Я спробував об'єднати церт і ключ, але отримав той самий результат.

Як імпортувати ключ?


1
Для цього вам потрібно написати трохи коду, і деталі залежать від формату приватного ключа, який ви намагаєтеся імпортувати. Який формат є вашим ключем? Чи можете ви пояснити, які інструменти використовували для створення ключа та сертифікату, які у вас є?
erickson

Про двосторонній SSL (сертифікат клієнта та сервера) з Spring Boot див. Stackoverflow.com/a/59317888/548473
Григорій

Відповіді:


73

Вірите чи ні, keytool не забезпечує такої основної функціональності, як імпорт приватного ключа до магазину ключів. Ви можете спробувати вирішити цю проблему, об'єднавши файл PKSC12 з приватним ключем у сховище ключів.

Або просто використовуйте більш зручний для користувача KeyMan від IBM для роботи з зберіганням ключів замість keytool.exe.


11
Відповідно до відповіді CoverosGene, keytool підтримує його з Java 6. Це посилання, яке він надав
Хаутман

Оскільки це вартий, для всього шуму з цього приводу найкращим посиланням є посилання @ Матея на "вирішення" на цю посаду 2008 року: cunning.sharp.fm/2008/06/importing_private_keys_into_a.html
cloudsurfin

2
Я слідував за відповіддю CoverosGene, і це спрацювало.
Robert3452

1
KeyMan не здається мені таким зручним для користувачів.
Різне

15
Перервана посилання. Будь ласка, включіть деталі рішення безпосередньо у відповідь :-(
lilalinux

536

Я використав наступні два кроки, які знайшов у коментарях / публікаціях, пов'язаних з іншими відповідями:

Перший крок: Перетворіть x.509 cert і введіть у файл pkcs12

openssl pkcs12 -export -in server.crt -inkey server.key \
               -out server.p12 -name [some-alias] \
               -CAfile ca.crt -caname root

Примітка. Переконайтеся, що ви вставили пароль у файл pkcs12 - інакше ви отримаєте нульовий виняток вказівника при спробі імпортувати його. (На випадок, якщо хтось інший болів цей головний біль). ( Спасибі jocull! )

Примітка 2. Ви можете додати -chainможливість збереження повного ланцюжка сертифікатів. ( Спасибі Мафуба )

Крок другий: Перетворіть файл pkcs12 у сховище Java

keytool -importkeystore \
        -deststorepass [changeit] -destkeypass [changeit] -destkeystore server.keystore \
        -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass some-password \
        -alias [some-alias]

Готово

ОПЦІЯЛЬНИЙ Крок нульовий: Створіть самопідписаний сертифікат

openssl genrsa -out server.key 2048
openssl req -new -out server.csr -key server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Ура!


12
Переконайтеся, що ви поставили пароль на файл p12 - інакше ви отримаєте нульовий посилання на виключення при спробі імпорту. (У випадку, якщо хтось інший болить головою)
Jocull

9
У моєму випадку на першому кроці параметр -CAfile ca.crt -caname rootнеправильно видав сертифікати CA. Натомість я використав-certfile concatenedCAFiles.pem
dcernahoschi

11
Не забудьте використовувати -chainаргумент з openssl, щоб включити повний ланцюжок сертифікатів у файл pfx / p12, якщо ви хочете, щоб це було у вашому сховищі ключів.
Мафуба

3
У середовищі Windows pvk2pfx(стандартний інструмент VS, доступний у вікні VS cmd) буде виплюнути - .pfxеквівалент а .p12. @ jocull поради все ще актуальні; поставте на нього пароль. Не opensslпотрібно.
Бен Мошер

9
Зокрема, для Tomcat важливо, щоб зберігання ключів і паролі ключів були однаковими. Коли ви імпортуєте .p12ключ, пароль оригіналу .p12.Tomcat не вдасться java.security.UnrecoverableKeyException: Cannot recover key. Іншими словами: якщо вам потрібно виконувати -deststorepass changeit -srcstorepass some-passwordз різними паролями, то ви повинні включати в себе -destkeypass changeit(з тим же паролем , як -deststorepass)
слов'янин

127

Keytool в Java 6 має таку можливість: Імпорт приватних ключів у сховище Java за допомогою keytool

Ось основні деталі з цієї публікації.

  1. Перетворіть існуючий cert в PKCS12 за допомогою OpenSSL. У запиті потрібен пароль або 2-й крок поскаржиться.

    openssl pkcs12 -export -in [my_certificate.crt] -inkey [my_key.key] -out [keystore.p12] -name [new_alias] -CAfile [my_ca_bundle.crt] -caname root
  2. Перетворіть PKCS12 у файл зберігання Java.

    keytool -importkeystore -deststorepass [new_keystore_pass] -destkeypass [new_key_pass] -destkeystore [keystore.jks] -srckeystore [keystore.p12] -srcstoretype PKCS12 -srcstorepass [pass_used_in_p12_keystore] -alias [alias_used_in_p12_keystore]

4
Відповідь @reto містить вміст цього посилання.
Мафуба

4
Як зазначає @Mafuba, ви все одно повинні створити окремий магазин клавіатури pkcs12 з інструментом, який не є java, як openssl - тоді це можна імпортувати в магазин jks за допомогою keytool, як зазначено у відповіді reto.
Mister_Tom

Одне, що робить це гарною відповіддю - це той факт, що вхідні сертифікати чітко вказані в дужках.
Містер Будріс

FWIW, висновок кроку 1 вже повинен використовуватися як сховище Java (тому крок 2 може не знадобитися - якщо тільки вам не потрібно імпортувати клавішу cert + у існуючу сховище ключів) - як уже згадувалося у попередній відповіді @ jaco0646
Джанака Бандара

9

І ще один:

#!/bin/bash

# We have:
#
# 1) $KEY : Secret key in PEM format ("-----BEGIN RSA PRIVATE KEY-----") 
# 2) $LEAFCERT : Certificate for secret key obtained from some
#    certification outfit, also in PEM format ("-----BEGIN CERTIFICATE-----")   
# 3) $CHAINCERT : Intermediate certificate linking $LEAFCERT to a trusted
#    Self-Signed Root CA Certificate 
#
# We want to create a fresh Java "keystore" $TARGET_KEYSTORE with the
# password $TARGET_STOREPW, to be used by Tomcat for HTTPS Connector.
#
# The keystore must contain: $KEY, $LEAFCERT, $CHAINCERT
# The Self-Signed Root CA Certificate is obtained by Tomcat from the
# JDK's truststore in /etc/pki/java/cacerts

# The non-APR HTTPS connector (APR uses OpenSSL-like configuration, much
# easier than this) in server.xml looks like this 
# (See: https://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html):
#
#  <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
#                SSLEnabled="true"
#                maxThreads="150" scheme="https" secure="true"
#                clientAuth="false" sslProtocol="TLS"
#                keystoreFile="/etc/tomcat6/etl-web.keystore.jks"
#                keystorePass="changeit" />
#

# Let's roll:    

TARGET_KEYSTORE=/etc/tomcat6/foo-server.keystore.jks
TARGET_STOREPW=changeit

TLS=/etc/pki/tls

KEY=$TLS/private/httpd/foo-server.example.com.key
LEAFCERT=$TLS/certs/httpd/foo-server.example.com.pem
CHAINCERT=$TLS/certs/httpd/chain.cert.pem

# ----
# Create PKCS#12 file to import using keytool later
# ----

# From https://www.sslshopper.com/ssl-converter.html:
# The PKCS#12 or PFX format is a binary format for storing the server certificate,
# any intermediate certificates, and the private key in one encryptable file. PFX
# files usually have extensions such as .pfx and .p12. PFX files are typically used 
# on Windows machines to import and export certificates and private keys.

TMPPW=$$ # Some random password

PKCS12FILE=`mktemp`

if [[ $? != 0 ]]; then
  echo "Creation of temporary PKCS12 file failed -- exiting" >&2; exit 1
fi

TRANSITFILE=`mktemp`

if [[ $? != 0 ]]; then
  echo "Creation of temporary transit file failed -- exiting" >&2; exit 1
fi

cat "$KEY" "$LEAFCERT" > "$TRANSITFILE"

openssl pkcs12 -export -passout "pass:$TMPPW" -in "$TRANSITFILE" -name etl-web > "$PKCS12FILE"

/bin/rm "$TRANSITFILE"

# Print out result for fun! Bug in doc (I think): "-pass " arg does not work, need "-passin"

openssl pkcs12 -passin "pass:$TMPPW" -passout "pass:$TMPPW" -in "$PKCS12FILE" -info

# ----
# Import contents of PKCS12FILE into a Java keystore. WTF, Sun, what were you thinking?
# ----

if [[ -f "$TARGET_KEYSTORE" ]]; then
  /bin/rm "$TARGET_KEYSTORE"
fi

keytool -importkeystore \
   -deststorepass  "$TARGET_STOREPW" \
   -destkeypass    "$TARGET_STOREPW" \
   -destkeystore   "$TARGET_KEYSTORE" \
   -srckeystore    "$PKCS12FILE" \
   -srcstoretype  PKCS12 \
   -srcstorepass  "$TMPPW" \
   -alias foo-the-server

/bin/rm "$PKCS12FILE"

# ----
# Import the chain certificate. This works empirically, it is not at all clear from the doc whether this is correct
# ----

echo "Importing chain"

TT=-trustcacerts

keytool -import $TT -storepass "$TARGET_STOREPW" -file "$CHAINCERT" -keystore "$TARGET_KEYSTORE" -alias chain

# ----
# Print contents
# ----

echo "Listing result"

keytool -list -storepass "$TARGET_STOREPW" -keystore "$TARGET_KEYSTORE"

9

Спочатку перетворите на p12:

openssl pkcs12 -export -in [filename-certificate] -inkey [filename-key] -name [host] -out [filename-new-PKCS-12.p12]

Створіть новий JKS з p12:

keytool -importkeystore -deststorepass [password] -destkeystore [filename-new-keystore.jks] -srckeystore [filename-new-PKCS-12.p12] -srcstoretype PKCS12

8

Так, це справді сумний факт, що keytool не має функцій для імпорту приватного ключа.

Для запису, наприкінці я пішов із описаним тут рішенням


6

У моєму випадку у мене був файл pem, який містив два сертифікати та зашифрований приватний ключ, який використовувався при взаємній автентифікації SSL. Отже, мій файл pem виглядав так:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C8BF220FC76AA5F9
...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Ось що я зробив:

Розділіть файл на три окремі файли, щоб кожен містив лише один запис, починаючи з «--- ПОЧАТОК ..» і закінчуючи рядками «--- ЗАКОН» .. Припустимо, у нас зараз три файли: cert1.pem cert2.pem і pkey.pem

Перетворити pkey.pem у формат DER, використовуючи openssl та наступний синтаксис:

openssl pkcs8 -topk8 -nocrypt -in pkey.pem -inform PEM -out pkey.der -outform DER

Зауважте, що якщо приватний ключ зашифрований, вам потрібно надати пароль (отримати його у постачальника оригінального файлу pem), щоб перетворити його у формат DER, openssl попросить вас такий пароль: "введіть фразу пропуску для pkey .pem: "Якщо конверсія буде успішною, ви отримаєте новий файл під назвою" pkey.der "

Створіть новий магазин ключів java та імпортуйте приватний ключ та сертифікати:

String keypass = "password";  // this is a new password, you need to come up with to protect your java key store file
String defaultalias = "importkey";
KeyStore ks = KeyStore.getInstance("JKS", "SUN");

// this section does not make much sense to me, 
// but I will leave it intact as this is how it was in the original example I found on internet:   
ks.load( null, keypass.toCharArray());
ks.store( new FileOutputStream ( "mykeystore"  ), keypass.toCharArray());
ks.load( new FileInputStream ( "mykeystore" ),    keypass.toCharArray());
// end of section..


// read the key file from disk and create a PrivateKey

FileInputStream fis = new FileInputStream("pkey.der");
DataInputStream dis = new DataInputStream(fis);
byte[] bytes = new byte[dis.available()];
dis.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

byte[] key = new byte[bais.available()];
KeyFactory kf = KeyFactory.getInstance("RSA");
bais.read(key, 0, bais.available());
bais.close();

PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
PrivateKey ff = kf.generatePrivate (keysp);


// read the certificates from the files and load them into the key store:

Collection  col_crt1 = CertificateFactory.getInstance("X509").generateCertificates(new FileInputStream("cert1.pem"));
Collection  col_crt2 = CertificateFactory.getInstance("X509").generateCertificates(new FileInputStream("cert2.pem"));

Certificate crt1 = (Certificate) col_crt1.iterator().next();
Certificate crt2 = (Certificate) col_crt2.iterator().next();
Certificate[] chain = new Certificate[] { crt1, crt2 };

String alias1 = ((X509Certificate) crt1).getSubjectX500Principal().getName();
String alias2 = ((X509Certificate) crt2).getSubjectX500Principal().getName();

ks.setCertificateEntry(alias1, crt1);
ks.setCertificateEntry(alias2, crt2);

// store the private key
ks.setKeyEntry(defaultalias, ff, keypass.toCharArray(), chain );

// save the key store to a file         
ks.store(new FileOutputStream ( "mykeystore" ),keypass.toCharArray());

(необов’язково) Перевірте вміст вашого нового магазину ключів:

keytool -list -keystore mykeystore -storepass password

Тип брелоки: JKS Постачальник магазинів: SUN

У вашій магазині брелоків є 3 записи

cn = ..., ou = ..., o = .., 2 вересня 2014 року, trustedCertEntry, відбиток сертифіката сертифіката (SHA1): 2C: B8: ...

importkey, 2 вересня 2014 р., PrivateKeyEntry, відбиток пальців сертифіката (SHA1): 9C: B0: ...

cn = ..., o = ...., 2 вересня 2014 року, trustedCertEntry, відбиток сертифікату (SHA1): 83:63: ...

(необов'язково) Перевірте свої сертифікати та приватний ключ у вашому новому магазині ключів на сервері SSL: (Ви можете увімкнути налагодження як параметр VM: -Djavax.net.debug = всі)

        char[] passw = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS", "SUN");
        ks.load(new FileInputStream ( "mykeystore" ), passw );

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passw);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sclx = SSLContext.getInstance("TLS");
        sclx.init( kmf.getKeyManagers(), tm, null);

        SSLSocketFactory factory = sclx.getSocketFactory();
        SSLSocket socket = (SSLSocket) factory.createSocket( "192.168.1.111", 443 );
        socket.startHandshake();

        //if no exceptions are thrown in the startHandshake method, then everything is fine..

Нарешті зареєструйте свої сертифікати в HttpsURLConnection, якщо плануєте ним користуватися:

        char[] passw = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS", "SUN");
        ks.load(new FileInputStream ( "mykeystore" ), passw );

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passw);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sclx = SSLContext.getInstance("TLS");
        sclx.init( kmf.getKeyManagers(), tm, null);

        HostnameVerifier hv = new HostnameVerifier()
        {
            public boolean verify(String urlHostName, SSLSession session)
            {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost()))
                {
                    System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };

        HttpsURLConnection.setDefaultSSLSocketFactory( sclx.getSocketFactory() );
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

Однак Бруно зауважив, що цей перевіряючий імен хоста неправильний: "Ваш перевіряльник імен хостів неправильний, session.getPeerHost () не повертає ім'я в сертифікаті, але ім'я, з яким ви з'єдналися (тобто тут urlHostName), тому це завжди відбувається бути правдою. Ви все одно повертаєте справжнє. - Бруно ". Це працювало для мене, але я був би вдячний, якщо хтось покаже мені, як написати гарну перевірку імені хоста.
Інтеркот

1
Звичайно, це буде "працювати" для вас, оскільки воно ніколи не призведе до помилок, навіть коли це повинно. Залиште перевіряльник імені хоста за замовчуванням, який використовується, HttpsURLConnectionа не намагатися написати власний. (Ще одна проблема у вашому прикладі полягає в тому, що ви використовуєте ту саму сховище ключів, як магазини брелоків і довірені магазини, що не завжди є гарною ідеєю ...)
Бруно

6

Використання сертифікатів Let’s Encrypt

Припустимо, що ви створили ваші сертифікати та приватні ключі за допомогою Let's Encrypt in/etc/letsencrypt/live/you.com :

1. Створити PKCS # 12 файл

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 \
        -name letsencrypt

Це поєднує ваш сертифікат SSL fullchain.pemта приватний ключ privkey.pemв один файл,pkcs.p12 .

Вам буде запропоновано пароль для pkcs.p12 .

У exportпараметр вказує , що файл PKCS # 12 буде створено , а не розібрані (від ручної ).

2. Створіть зберігання клавіш Java

keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 \
        -srcstoretype PKCS12 -alias letsencrypt

Якщо keystore.jksйого не існує, він буде створений з pkcs.12файлом, створеним вище. Інакше ви імпортуєте pkcs.12у існуючу сховище ключів.


Ці вказівки отримані з цієї публікації в блозі .

Ось докладніше про різні види файлів у /etc/letsencrypt/live/you.com/.


5

Виходячи з вищенаведених відповідей, ось як створити абсолютно новий сховище ключів для вашого веб-сервера на базі Java, з незалежно створеного комодо-серту та приватного ключа за допомогою keytool (потрібно JDK 1.6+)

  1. Запустіть цю команду і в запиті пароля введіть деякі паролі - "server.crt" - це сервер вашого сервера, а "server.key" - приватний ключ, який ви використовували для видачі CSR: openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name www.yourdomain.com -CAfile AddTrustExternalCARoot.crt -caname "AddTrust External CA Root"

  2. Потім використовуйте keytool для перетворення магазину клавіш p12 в сховище jks: keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

Потім імпортуйте два інших кореневих / проміжних серта, які ви отримали від Comodo:

  1. Імпорт COMODORSAAddTrustCA.crt: keytool -import -trustcacerts -alias cert1 -file COMODORSAAddTrustCA.crt -keystore keystore.jks

  2. Імпорт COMODORSADomainValidationSecureServerCA.crt: keytool -import -trustcacerts -alias cert2 -file COMODORSADomainValidationSecureServerCA.crt -keystore keystore.jks


4

Ви можете скористатися цими кроками, щоб імпортувати ключ до існуючої сховища ключів. Інструкції поєднуються з відповідей у ​​цій темі та інших сайтах. Ці інструкції працювали для мене (магазин брелоків Java):

  1. Біжи

openssl pkcs12 -export -in yourserver.crt -inkey yourkey.key -out server.p12 -name somename -certfile yourca.crt -caname root

(Якщо потрібно, поставте опцію -chain. Встановити це не вдалося для мене). Тут буде запропоновано пароль - ви повинні вказати правильний пароль, інакше ви отримаєте помилку (помилка заголовка чи помилка заміни тощо).

  1. Він попросить вас ввести новий пароль - тут ви повинні ввести пароль - введіть що-небудь, але запам’ятайте його. (Припустимо, ви введете Арагорн).
  2. Це створить файл server.p12 у форматі pkcs.
  3. Тепер, щоб імпортувати його у *.jksфайл запуску:
    keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore yourexistingjavakeystore.jks -deststoretype JKS -deststorepass existingjavastorepassword -destkeypass existingjavastorepassword
    (Дуже важливо - не виключайте параметри deststorepass та destkeypass.)
  4. Він запитає пароль для зберігання ключів src. Введіть Арагорн і натисніть Enter. Сертифікат і ключ зараз імпортуються у вашу існуючу сховище Java.

3

Попередні відповіді правильно вказують, що це можна зробити лише за допомогою стандартних інструментів JDK, попередньо перетворивши файл JKS у формат PKCS №12. Якщо вам цікаво, я зібрав компактну утиліту для імпорту ключів, похідних OpenSSL, у формат клавіш JKS-форматування, без необхідності спочатку конвертувати сховище ключів у PKCS # 12: http://commandlinefanatic.com/cgi-bin/showarticle. cgi? article = art049

Ви б використовували пов'язану утиліту, як це:

$ openssl req -x509 -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/CN=localhost"

(підпишіть CSR, поверніть localhost.cer)

$ openssl rsa -in localhost.key -out localhost.rsa
Enter pass phrase for localhost.key:
writing RSA key
$ java -classpath . KeyImport -keyFile localhost.rsa -alias localhost -certificateFile localhost.cer -keystore localhost.jks -keystorePassword changeit -keystoreType JKS -keyPassword changeit

Просто посилання на власну бібліотеку (або утиліту) не є гарною відповіддю. Посилання на нього, пояснення, чому він вирішує проблему, надання коду, використовуючи його для цього, та відмова від неї дає кращу відповідь. Див.: Як я можу зв’язатись із зовнішнім ресурсом у зручному для громади спосіб?
Могсдад

Не впевнений, що ви маєте на увазі під "відмовою", але я додав приклад.
Джошуа Девіс

Чудово! Це зауважений коментар, тому частина не поширюється - відмовлятись означає повідомити про свою приналежність до пов’язаного товару чи послуги, що ви зробили із "Я разом уклав ..."
Mogsdad

3

Якщо у вас є файл PEM (наприклад server.pem), що містить:

  • довірений сертифікат
  • приватний ключ

тоді ви можете імпортувати сертифікат і ключ у сховище JKS таким чином:

1 ) Скопіюйте приватний ключ з PEM-файлу у файл ascii (наприклад server.key)

2 ) Скопіюйте kert з файлу PEM у файл ascii (наприклад server.crt)

3 ) Експорт cert і ключ у файл PKCS12:

$ openssl pkcs12 -export -in server.crt -inkey server.key \
                 -out server.p12 -name [some-alias] -CAfile server.pem -caname root
  • файл PEM може бути використаний як аргумент до -CAfileпараметра .
  • Вам буде запропоновано ввести пароль "експорту".
  • якщо це робити в git bash, тоді додайте winptyдо початку команди, щоб можна було ввести пароль експорту.

4 ) Перетворіть файл PKCS12 у сховище ключів JKS:

$ keytool -importkeystore -deststorepass changeit -destkeypass changeit \
          -destkeystore keystore.jks  -srckeystore server.p12 -srcstoretype PKCS12 \
          -srcstorepass changeit
  • srcstorepassпароль повинен збігатися з паролем на експорт , починаючи з кроку 3)

3

Те, що я намагався досягти, - це використовувати вже наданий приватний ключ та сертифікат для підписання повідомлення, яке відбудеться десь, де потрібно переконатися, що повідомлення надходить від мене (підписують приватні ключі, коли відкриті ключі шифруються).

Отже, якщо у вас вже є .key файл та .crt файл?

Спробуйте це:

Крок 1: Перетворіть ключ і cert у файл .p12

openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -name alias -out yourconvertedfile.p12

Крок 2: Імпортуйте ключ і створіть .jsk файл за допомогою однієї команди

keytool -importkeystore -deststorepass changeit -destkeystore keystore.jks -srckeystore umeme.p12 -srcstoretype PKCS12

Крок 3. У вашій Java:

char[] keyPassword = "changeit".toCharArray();

KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyStoreData = new FileInputStream("keystore.jks");

keyStore.load(keyStoreData, keyPassword);
KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(keyPassword);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry("alias", entryPassword);

System.out.println(privateKeyEntry.toString());

Якщо вам потрібно підписати якусь рядок за допомогою цього ключа, виконайте наступне:

Крок 1. Перетворіть текст, який ви бажаєте зашифрувати

byte[] data = "test".getBytes("UTF8");

Крок 2. Отримайте приватний ключ, кодований base64

keyStore.load(keyStoreData, keyPassword);

//get cert, pubkey and private key from the store by alias
Certificate cert = keyStore.getCertificate("localhost");
PublicKey publicKey = cert.getPublicKey();
KeyPair keyPair = new KeyPair(publicKey, (PrivateKey) key);

//sign with this alg
Signature sig = Signature.getInstance("SHA1WithRSA");
sig.initSign(keyPair.getPrivate());
sig.update(data);
byte[] signatureBytes = sig.sign();
System.out.println("Signature:" + Base64.getEncoder().encodeToString(signatureBytes));

sig.initVerify(keyPair.getPublic());
sig.update(data);

System.out.println(sig.verify(signatureBytes));

Список літератури:

  1. Як імпортувати існуючий сертифікат x509 та приватний ключ у сховищі Java для використання у SSL?
  2. http://tutorials.jenkov.com/java-cryptography/keystore.html
  3. http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm
  4. Як підписати рядок за допомогою приватного ключа

Підсумкова програма

public static void main(String[] args) throws Exception {

    byte[] data = "test".getBytes("UTF8");

    // load keystore
    char[] keyPassword = "changeit".toCharArray();

    KeyStore keyStore = KeyStore.getInstance("JKS");
    //System.getProperty("user.dir") + "" < for a file in particular path 
    InputStream keyStoreData = new FileInputStream("keystore.jks");
    keyStore.load(keyStoreData, keyPassword);

    Key key = keyStore.getKey("localhost", keyPassword);

    Certificate cert = keyStore.getCertificate("localhost");

    PublicKey publicKey = cert.getPublicKey();

    KeyPair keyPair = new KeyPair(publicKey, (PrivateKey) key);

    Signature sig = Signature.getInstance("SHA1WithRSA");

    sig.initSign(keyPair.getPrivate());
    sig.update(data);
    byte[] signatureBytes = sig.sign();
    System.out.println("Signature:" + Base64.getEncoder().encodeToString(signatureBytes));

    sig.initVerify(keyPair.getPublic());
    sig.update(data);

    System.out.println(sig.verify(signatureBytes));
}

1

Просто зробіть сховище ключів PKCS12, Java може використовувати його прямо зараз. Насправді, якщо ви перераховуєте сховище ключів у стилі Java, сам keytool попереджає вас про те, що PKCS12 є бажаним форматом.

openssl pkcs12 -export -in server.crt -inkey server.key \
               -out server.p12 -name [some-alias] \
               -CAfile ca.crt -caname root -chain

Ви мали отримати всі три файли (server.crt, server.key, ca.crt) від свого постачальника сертифікатів. Я не впевнений, що насправді означає "root -caname root", але, здається, його потрібно вказати саме так.

У коді Java обов’язково вкажіть правильний тип зберігання клавіш.

KeyStore.getInstance("PKCS12")

Таким чином я отримав свій сертифікат SSL, який видав comodo.com, добре працює в NanoHTTPD.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.