Как я могу перечислить / экспортировать закрытые ключи из хранилища ключей?
Как список и экспортировать закрытый ключ из хранилища ключей?
9 ответов:
часть кода первоначально из примера 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); }
экспорт закрытых ключей появился на Солнце форумов пару месяцев назад, и 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; } }
Примечание: этот пакет Солнца пользы,что такое "плохо".
Если вы можете скачать 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
вы можете извлечь закрытый ключ из хранилища ключей с помощью Java6 и OpenSSL. Все это зависит от того, что и Java, и OpenSSL поддерживают PKCS#12-форматированные хранилища ключей. Чтобы сделать извлечение, вы сначала используете
keytool
конвертировать в стандартный формат. Убедитесь, что вы используйте один и тот же пароль для обоих файлов (пароль закрытого ключа, а не пароль хранилища ключей) или вы получите нечетные сбои позже на втором шаге.keytool -importkeystore -srckeystore keystore.jks \ -destkeystore intermediate.p12 -deststoretype PKCS12
далее, используйте OpenSSL, чтобы сделать добыча УГР:
openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes
вы должны быть в состоянии обрабатывать этот файл PEM достаточно легко; это простой текст с закодированным незашифрованным закрытым ключом и сертификатом(сертификатами) внутри него (в довольно очевидном формате).
когда вы делаете это, позаботьтесь о том, чтобы сохранить созданные файлы в безопасности. Они содержат секретные данные. Ничто не предупредит вас, если вы не в состоянии обеспечить их правильно. самый простой способ их защиты-сделать все это в каталоге, который не делает иметь любые права доступа для любого пользователя. И никогда не ставьте пароль в командной строке или в переменных окружения; это слишком легко для других пользователей, чтобы захватить.
Если вам не нужно делать это программно, но просто хотите управлять своими ключами, то я уже давно использую бесплатный инструмент KeyMan от IBM. Очень хорошо для экспорта закрытого ключа в файл PFX (тогда вы можете легко использовать OpenSSL для управления им, извлечения его, изменения pwds и т. д.).
выберите Хранилище, выберите запись закрытого ключа, затем File - >Save to a pkcs12 file (*.pfx-файл, как правило). Затем вы можете просмотреть содержимое с помощью:
$ openssl pkcs12-в mykeyfile.pfx-info
вот более короткая версия приведенного выше кода, в 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-----"
для разработки android, для преобразования хранилища ключей, созданного в eclipse ADT, в открытый ключ и закрытый ключ, используемый в SignApk.фляги:
экспортировать закрытый ключ:
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
изменить личные.ЮАР.pem и оставьте" - - - - - начните закрытый ключ- - - - - "to" - - - - - конец закрытого ключа - - - - - " абзац, затем:
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
этот вопрос возник на StackExchange security, одним из предложений было использовать Keystore explorer
только что попробовал, это работает очень хорошо, и я настоятельно рекомендую его.
прежде всего, будьте осторожны! Вся ваша безопасность зависит от... э-э...конфиденциальность вашего личные ключи. Keytool не имеет встроенного экспорта ключей, чтобы избежать случайного раскрытия этого чувствительного материала, поэтому вы можете рассмотреть некоторые дополнительные гарантии, которые могут быть введены для защиты ваших экспортированных ключей.
вот простой код, который дает вам незашифрованный PKCS #8 PrivateKeyInfo, который может быть использован OpenSSL (см. из его утилиты 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 и вывести его в желаемом формате. Это было бы хорошей темой для последующего вопроса.
еще один отличный инструмент KeyStore Explorer:http://keystore-explorer.sourceforge.net/
еще один менее традиционный, но, возможно, более простой способ сделать это-с JXplorer. Хотя этот инструмент предназначен для просмотра каталогов LDAP, он имеет простой в использовании графический интерфейс для работы хранилища. Одна из таких функций в графическом интерфейсе может экспортировать закрытые ключи из хранилища ключей JKS.