Как мне вывести / экспортировать закрытые ключи из хранилища ключей? - PullRequest
58 голосов
/ 29 сентября 2008

Как мне вывести и экспортировать закрытый ключ из хранилища ключей?

Ответы [ 9 ]

103 голосов
/ 08 апреля 2011

Вы можете извлечь закрытый ключ из хранилища ключей с помощью Java6 и OpenSSL. Все это зависит от того, что и Java, и OpenSSL поддерживают хранилища ключей в формате PKCS # 12. Для извлечения вы сначала используете keytool для преобразования в стандартный формат. Убедитесь, что вы используете один и тот же пароль для обоих файлов (пароль закрытого ключа, а не пароль хранилища ключей) , иначе вы получите странные сбои позже на втором этапе.

keytool -importkeystore -srckeystore keystore.jks \
    -destkeystore intermediate.p12 -deststoretype PKCS12

Затем используйте OpenSSL для извлечения в PEM:

openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes

Вы должны быть в состоянии обработать этот файл PEM достаточно легко; это обычный текст с закодированным незашифрованным закрытым ключом и сертификатами внутри него (в довольно очевидном формате).

Когда вы делаете это, заботитесь о сохранности созданных файлов. Они содержат секретные полномочия. Ничто не предупредит вас, если вам не удастся защитить их правильно. Самый простой способ защитить их - это сделать все это в каталоге, который не имеет никаких прав доступа для кого-либо, кроме пользователя. И никогда не ставьте свой пароль в командной строке или в переменных окружения; другим пользователям слишком просто его захватить.

31 голосов
/ 29 сентября 2008

Часть кода, изначально взятая из Example Depot, для перечисления всех псевдонимов в хранилище ключей:

    // Load input stream into keystore
    keystore.load(is, password.toCharArray());

    // List the aliases
    Enumeration aliases = keystore.aliases();
    for (; aliases.hasMoreElements(); ) {
        String alias = (String)aliases.nextElement();

        // Does alias refer to a private key?
        boolean b = keystore.isKeyEntry(alias);

        // Does alias refer to a trusted certificate?
        b = keystore.isCertificateEntry(alias);
    }

Экспорт закрытых ключей появился на форумах Sun пару месяцев назад, и u: turingcompleter разработал класс DumpPrivateKey для вставки в ваше приложение. *

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import sun.misc.BASE64Encoder;

public class DumpPrivateKey {
     /**
     * Provides the missing functionality of keytool
     * that Apache needs for SSLCertificateKeyFile.
     *
     * @param args  <ul>
     *              <li> [0] Keystore filename.
     *              <li> [1] Keystore password.
     *              <li> [2] alias
     *              </ul>
     */
    static public void main(String[] args)
    throws Exception {
        if(args.length < 3) {
          throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
        }
        final String keystoreName = args[0];
        final String keystorePassword = args[1];
        final String alias = args[2];
        final String keyPassword = getKeyPassword(args,keystorePassword);
        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
        Key key = ks.getKey(alias, keyPassword.toCharArray());
        String b64 = new BASE64Encoder().encode(key.getEncoded());
        System.out.println("-----BEGIN PRIVATE KEY-----");
        System.out.println(b64);
        System.out.println("-----END PRIVATE KEY-----");
    }
    private static String getKeyPassword(final String[] args, final String keystorePassword)
    {
       String keyPassword = keystorePassword; // default case
       if(args.length == 4) {
         keyPassword = args[3];
       }
       return keyPassword;
    }
}

Примечание: этот пакет Sun использует , что является «плохой вещью» .
Если вы можете загрузить Apache Commons Code , вот версия, которая будет скомпилирована без предупреждения:

javac -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey.java

и даст тот же результат:

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
//import sun.misc.BASE64Encoder;
import org.apache.commons.codec.binary.Base64;

public class DumpPrivateKey {
     /**
     * Provides the missing functionality of keytool
     * that Apache needs for SSLCertificateKeyFile.
     *
     * @param args  <ul>
     *              <li> [0] Keystore filename.
     *              <li> [1] Keystore password.
     *              <li> [2] alias
     *              </ul>
     */
    static public void main(String[] args)
    throws Exception {
        if(args.length < 3) {
          throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
        }
        final String keystoreName = args[0];
        final String keystorePassword = args[1];
        final String alias = args[2];
        final String keyPassword = getKeyPassword(args,keystorePassword);
        KeyStore ks = KeyStore.getInstance("jks");
        ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
        Key key = ks.getKey(alias, keyPassword.toCharArray());
        //String b64 = new BASE64Encoder().encode(key.getEncoded());
        String b64 = new String(Base64.encodeBase64(key.getEncoded(),true));
        System.out.println("-----BEGIN PRIVATE KEY-----");
        System.out.println(b64);
        System.out.println("-----END PRIVATE KEY-----");
    }
    private static String getKeyPassword(final String[] args, final String keystorePassword)
    {
       String keyPassword = keystorePassword; // default case
       if(args.length == 4) {
         keyPassword = args[3];
       }
       return keyPassword;
    }
}

Вы можете использовать его так:

java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat
6 голосов
/ 29 сентября 2008

Если вам не нужно делать это программно, а просто управлять своими ключами, то я давно пользуюсь бесплатным инструментом IBM KeyMan. Очень хорошо для экспорта закрытого ключа в файл PFX (тогда вы можете легко использовать OpenSSL для манипулирования им, извлечения, изменения pwds и т. Д.).

https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc

Выберите хранилище ключей, выберите запись личного ключа, затем Файл-> Сохранить в файл pkcs12 (обычно * .pfx). Затем вы можете просмотреть содержимое с помощью:

$ openssl pkcs12 -in mykeyfile.pfx -info

5 голосов
/ 02 февраля 2012

Вот более короткая версия приведенного выше кода в Groovy. Также имеет встроенную кодировку base64:

import java.security.Key
import java.security.KeyStore

if (args.length < 3)
        throw new IllegalArgumentException('Expected args: <Keystore file> <Keystore format> <Keystore password> <alias> <key password>')

def keystoreName = args[0]
def keystoreFormat = args[1]
def keystorePassword = args[2]
def alias = args[3]
def keyPassword = args[4]

def keystore = KeyStore.getInstance(keystoreFormat)
keystore.load(new FileInputStream(keystoreName), keystorePassword.toCharArray())
def key = keystore.getKey(alias, keyPassword.toCharArray())

println "-----BEGIN PRIVATE KEY-----"
println key.getEncoded().encodeBase64()
println "-----END PRIVATE KEY-----"
4 голосов
/ 18 июня 2014

Этот вопрос возник в связи с безопасностью stackexchange, одним из предложений было использование Keystore explorer

https://security.stackexchange.com/questions/3779/how-can-i-export-my-private-key-from-a-java-keytool-keystore

Только что попробовав, он работает очень хорошо, и я настоятельно рекомендую это.

4 голосов
/ 29 ноября 2011

для разработки под Android, преобразовать хранилище ключей, созданное в eclipse ADT, в открытый ключ и закрытый ключ, используемый в SignApk.jar:

экспорт закрытого ключа:

keytool.exe -importkeystore -srcstoretype JKS -srckeystore my-release-key.keystore -deststoretype PKCS12 -destkeystore keys.pk12.der
openssl.exe pkcs12 -in keys.pk12.der -nodes -out private.rsa.pem

отредактируйте файл private.rsa.pem и оставьте "----- BEGIN PRIVATE KEY -----" в "----- END PRIVATE KEY -----", затем:

openssl.exe base64 -d -in private.rsa.pem -out private.rsa.der

экспорт открытого ключа:

keytool.exe -exportcert -keystore my-release-key.keystore -storepass <KEYSTORE_PASSWORD> -alias alias_name -file public.x509.der

знак apk:

java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk
3 голосов
/ 02 февраля 2015

Еще одним отличным инструментом является KeyStore Explorer: http://keystore -explorer.sourceforge.net /

3 голосов
/ 29 сентября 2008

Прежде всего, будьте осторожны! Вся ваша безопасность зависит от & hellip; эр & hellip; конфиденциальность ваших личных ключей. В Keytool не встроен экспорт ключей, чтобы избежать случайного раскрытия этого секретного материала, поэтому вы можете рассмотреть некоторые дополнительные меры предосторожности, которые могут быть введены место для защиты ваших экспортируемых ключей.

Вот простой код, который дает незашифрованный PKCS # 8 PrivateKeyInfo, который может использоваться OpenSSL (см. Параметр -nocrypt его утилиты pkcs8 ):

KeyStore keys = ...
char[] password = ...
Enumeration<String> aliases = keys.aliases();
while (aliases.hasMoreElements()) {
  String alias = aliases.nextElement();
  if (!keys.isKeyEntry(alias))
    continue;
  Key key = keys.getKey(alias, password);
  if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
    /* Most PrivateKeys use this format, but check for safety. */
    try (FileOutputStream os = new FileOutputStream(alias + ".key")) {
      os.write(key.getEncoded());
      os.flush();
    }
  }
}

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

1 голос
/ 13 июля 2012

Другой, менее традиционный, но, возможно, более простой способ сделать это - JXplorer Хотя этот инструмент предназначен для просмотра каталогов LDAP, он имеет простой в использовании графический интерфейс для работы с хранилищами ключей. Одна из таких функций в графическом интерфейсе может экспортировать закрытые ключи из хранилища ключей JKS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...