2011-07-02 12 views
25

Podczas próby odczytania klucza prywatnego RSA z pliku za pomocą metodybłąd parse skostniały, a nie sekwencja

public PrivateKey getPrivateKey() 
     throws NoSuchAlgorithmException, 
     InvalidKeySpecException, IOException { 

    final InputStream inputStream = getClass().getClassLoader() 
        .getResourceAsStream("privatekey"); 
    byte[] privKeyBytes = null; 
    try { 
     privKeyBytes = IOUtils.toByteArray(inputStream); 
    } catch (final IOException exception) { 
     LOGGER.error("", exception); 
     IOUtils.closeQuietly(inputStream); 
    } 

    LOGGER.debug("privKeyBytes: {}", privKeyBytes); 

    String BEGIN = "-----BEGIN RSA PRIVATE KEY-----"; 
    String END = "-----END RSA PRIVATE KEY-----"; 
    String str = new String(privKeyBytes); 
    if (str.contains(BEGIN) && str.contains(END)) { 
     str = str.substring(BEGIN.length(), str.lastIndexOf(END)); 
    } 

    KeyFactory fac = KeyFactory.getInstance("RSA"); 
    EncodedKeySpec privKeySpec = 
      new PKCS8EncodedKeySpec(Base64.decode(str.getBytes())); 
    return fac.generatePrivate(privKeySpec); 
} 

otrzymuję wyjątek

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:200) ~[na:1.6.0_23] 
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:342) ~[na:1.6.0_23] 

na fac.generatePrivate (privKeySpec) połączenie.

Co oznacza ten błąd?

Dzięki

Dmitri

Odpowiedz

37

Oznacza to klucz nie jest w formacie PKCS # 8. Najłatwiej jest użyć polecenia openssl pkcs8 -topk8 <...other options...>, aby raz przekonwertować klucz. Alternatywnie możesz użyć klasy PEMReader z Bouncycastle lightweight API.

+20

Dzięki, to działało. Oto polecenie: openssl pkcs8 -topk8 -nocrypt -in myrsakey.pem -out myrsakey_pcks8 –

32

Miałem ten sam problem, a format klucza NIE był faktycznym problemem.
Wszystko co musiałem zrobić, aby pozbyć się tego wyjątku było zadzwonić

java.security.Security.addProvider(
     new org.bouncycastle.jce.provider.BouncyCastleProvider() 
); 


i wszystko działało

+0

To rozwiązanie naprawdę działało. Dzięki. – user1919346

+0

To jest rozwiązanie! To działa! – Denny

+0

Rozwiązanie działa, ale jaka jest racjonalność tego rozwiązania? – user1918858

-1

Dla mnie brakowało OID w kluczu publicznym. Musiałem poprawić, że na stronie iOS z wykorzystaniem pomocy stąd: http://blog.wingsofhermes.org/?p=42

Również mój klucz publiczny nie musiał być lanego do RSAPublicKey, średnia pracował dobrze:

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes); 
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec); 
+1

op mówił o PrivateKey – lznt

4

Musisz rób swój plik PCKS8 ze swojego prywatnego klucza!

private.pem => nazwa pliku klucza prywatnego

openssl genrsa wymeldowanie private.pem 1024

public_key.pem => nazwa pliku klucza publicznego

openssl rsa -in prywatne. pem -pubout -outform PEM -out public_key.pem

private_key.pem => nazwa klucza prywatnego w formacie PCKS8! można tylko czytać ten format w java

openssl pkcs8 -topk8 -inform PEM -in private.pem wymeldowanie private_key.pem -nocrypt

+1

To był mój problem - plik został wygenerowany przy użyciu 'genrsa', który tworzy format PKCS # 1 (jest to format ładowany przez OP, jak widać przez nagłówek' BEGIN RSA PRIVATE KEY') , natomiast PKCS # 8 to inny format (w kodowaniu PEM można wykryć z powodu innego nagłówka: 'BEGIN PRIVATE KEY'). Mój generator kluczy wygląda teraz tak: 'openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out private.pem' – Guss

+0

Czy masz podobny generator kluczy do klucza prywatnego WE? –

Powiązane problemy