Jak wyświetlić / wyeksportować klucze prywatne z magazynu kluczy?

Jak wyeksportować klucz prywatny z magazynu kluczy?

Author: ScArcher2, 2008-09-29

9 answers

Fragment kodu oryginalnego z przykładowego magazynu do wyświetlenia wszystkich aliasów w magazynie kluczy:

    // 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);
    }

Eksport kluczy prywatnych pojawił się na Sun forums kilka miesięcy temu, a u:turingcompleter wymyślił klasę DumpPrivateKey do wszywania do Twojej aplikacji.

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;
    }
}

Uwaga: Ten pakiet używa słońca, co jest "złą rzeczą" .
Jeśli możesz pobrać kod Apache commons , Oto wersja, która będzie kompilowana bez warning:

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

I da ten sam wynik:

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;
    }
}

Możesz go używać tak:

java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat
 31
Author: ConroyP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-02 09:50:46

Możesz wyodrębnić klucz prywatny z magazynu kluczy za pomocą Java6 i OpenSSL. Wszystko zależy od tego, że zarówno Java, jak i OpenSSL obsługują sformatowane w PKCS#12 keystore. Aby wykonać ekstrakcję, najpierw użyj keytool, Aby przekonwertować do standardowego formatu. Upewnij się, że używaj tego samego hasła dla obu plików (hasło klucza prywatnego, nie hasło do magazynu kluczy) albo dostaniesz dziwne niepowodzenia później w drugim kroku.

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

Następnie użyj OpenSSL do ekstrakcji PEM:

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

Powinieneś być w stanie obsłużyć ten plik PEM wystarczająco łatwo; jest to zwykły tekst z zakodowanym niezaszyfrowanym kluczem prywatnym i certyfikatami wewnątrz niego (w dość oczywistym formacie).

gdy to zrobisz, zadbaj o bezpieczeństwo utworzonych plików. Zawierają tajne poświadczenia. Nic cię nie ostrzega, jeśli nie zabezpieczysz ich prawidłowo. najprostszą metodą ich zabezpieczenia jest zrobienie tego w katalogu, który nie ma żadnych praw dostępu dla nikogo innego niż użytkownik. I nigdy nie umieszczaj hasła w wierszu poleceń ani w zmiennych środowiskowych; przechwycenie go jest zbyt łatwe dla innych użytkowników.

 102
Author: Donal Fellows,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-04 15:34:51

Jeśli nie musisz tego robić programowo, ale po prostu chcesz zarządzać kluczami, to od dawna używam darmowego narzędzia IBM KeyMan. Bardzo przydatne do eksportowania klucza prywatnego do pliku PFX (wtedy możesz łatwo użyć OpenSSL do manipulowania nim, wyodrębniania go, zmiany PWD, itp.).

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

Wybierz swój keystore, wybierz klucz prywatny wpis, a następnie Plik - > Zapisz do pliku pkcs12 (*.pfx, zazwyczaj). Możesz następnie wyświetlić zawartość za pomocą:

$ OpenSSL pkcs12-in mykeyfile.pfx-info

 6
Author: DustinB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-07 17:41:00

Oto krótsza wersja powyższego kodu, w Groovy. Posiada również wbudowane kodowanie 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-----"
 5
Author: jrk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-01 23:32:48

Dla rozwoju Androida, aby przekonwertować keystore utworzony w eclipse ADT na klucz publiczny i klucz prywatny używany w SignApk.jar:

Eksport klucza prywatnego:

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

Edycja prywatna.rsa.pem i pozostawić" - - - - - BEGIN PRIVATE KEY- - - - - "do akapitu" - - - - - END PRIVATE KEY - - - - -", następnie:

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

Eksport klucza publicznego:

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

Znak apk:

java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk
 4
Author: diyism,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-29 09:59:05

To pytanie pojawiło się na temat bezpieczeństwa stackexchange, jedną z sugestii było użycie keystore explorer

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

Po wypróbowaniu działa naprawdę dobrze i zdecydowanie polecam.

 4
Author: PhilDin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 10:45:55

Po pierwsze, bądź ostrożny! Twoje bezpieczeństwo zależy od prywatności Twoich prywatnych kluczy. Keytool nie ma wbudowanego eksportu kluczy, aby uniknąć przypadkowego ujawnienia tego wrażliwego materiału, więc warto rozważyć dodatkowe zabezpieczenia, które można zastosować w celu ochrony eksportowanych kluczy.

Oto prosty kod, który daje Ci niezaszyfrowane PKCS # 8 PrivateKeyInfo, które mogą być używane przez OpenSSL (Zobacz opcję -nocrypt jej pkcs8 użyteczność):

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();
    }
  }
}

Jeśli potrzebujesz innych formatów, możesz użyć KeyFactory, aby uzyskać przejrzystą specyfikację kluczy dla różnych typów kluczy. Następnie możesz uzyskać na przykład prywatny wykładnik klucza prywatnego RSA i wydrukować go w pożądanym formacie. To byłby dobry temat na kolejne pytanie.

 3
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-10 16:09:22

Kolejnym świetnym narzędziem jest Keystore Explorer: http://keystore-explorer.sourceforge.net/

 3
Author: Davio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-02 09:54:51

Innym mniej konwencjonalnym, ale prawdopodobnie łatwiejszym sposobem na to jest JXplorer. Chociaż to narzędzie jest przeznaczone do przeglądania katalogów LDAP, ma łatwy w użyciu GUI do manipulowania kluczami. Jedna z takich funkcji w GUI może eksportować klucze prywatne z magazynu kluczy JKS.

 1
Author: Kkkev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-13 09:31:02