2013-08-21 12 views
6

Ich möchte den privaten Schlüssel aus einer Zeichenfolge (eine .pem Datei) in Java generieren.Wie generiere ich RSA Private Schlüssel aus * pem Zeichenfolge in Java

private static final String test = "-----BEGIN RSA PRIVATE KEY-----\n" + 
     "MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" + 
// and so on 
     "-----END RSA PRIVATE KEY-----"; 

try { 
    String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", ""); 
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); 

    byte [] encoded = Base64.decode(privKeyPEM); 

    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    PrivateKey privKey = kf.generatePrivate(keySpec); 
} 
catch (Exception e) { 
    e.printStackTrace(); 
} 

Die letzte Zeile (generatePrivate Funktion) wirft diese Ausnahme:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
    at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source) 
    at java.security.KeyFactory.generatePrivate(Unknown Source) 
    at Test.main(Test.java:52) 
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source) 
    at sun.security.pkcs.PKCS8Key.decode(Unknown Source) 
    at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source) 
    at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source) 
    at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source) 
    ... 3 more 

Wenn ich den privaten Schlüssel auf den Wert ändern aus einer .der Datei funktioniert es richtig, aber ich brauche die privat zu erzeugen Schlüsseldatei aus einer .pem Datei.

Ich habe einen Screenshot der Bytes als String (einmal hart-codiert mit \ n und einmal hart-codiert ohne \ n) und einmal aus der Datei gedruckt.

Bigger Image

Output

Das Seltsame ist, dass die Ausgabe von der Datei mit dem Ausgang von den Saiten unterschiedlich ist. Wenn ich versuche, eine .der Datei mit Base64 zu codieren, ist das Ergebnis anders als die Zeichenfolge in der Datei .pem. Warum ist das so?

+0

Haben Sie überhaupt eine Antwort gefunden? –

+0

@SankarP nein, nicht wirklich. – Niklas

+0

okay. Ich habe die Lösung gefunden. Schlüssel, die mit "----- BEGIN RSA PRIVATE KEY" beginnen, sind pkcs1-kodierte Dateien. Diese pkcs1-Codierung wird von Java nur unterstützt, wenn Sie eine externe Bibliothek wie BouncyCastle verwenden. Ich bin gestern auf das gleiche Problem gestoßen und habe nach ca. 8 Stunden die Lösung gefunden. Wenn Sie den privaten Schlüssel mit pkcs8 verschlüsseln, wird es wie "--- BEGIN PRIVATE KEY ---" beginnen, was durch das Lager-Java gehandhabt wird. HTH. –

Antwort

1

Sie sagen, dass die letzte Zeile Ausnahme wirft, dh

PrivateKey privKey = kf.generatePrivate(keySpec);

Above Linie auf keyspecs arbeitet korrekt eingestellt ist, das heißt

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

So eigentliche Problem mit codierten Bytes Array. Haben Sie System.out nach byte [] encoded = Base64.decode(privKeyPEM); getan und sehen, was die Ausgabe ist.

Ich verstehe, dass, wenn die Nachricht im MIME-Format ist, dann nach bestimmten Zeichen eine Kombination von Wagenrücklauf und Zeilenumbruch angehängt, so dass die Zeichenfolgen nicht zu lang für E-Mail-System oder wo auch immer Sie es verwenden.

Der letzte Stringtest hat '\ n' im Originaltext, den Sie verwenden. Sie haben von anderen Text in unter Leitung loszuwerden,

String privKeyPEM = test.replace("-----BEGIN RSA PRIVATE KEY-----\n", ""); 
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); 

Aber sehen Sie die Zeichenfolge,

"MIIEpAIBAAKCAQEAvcCH8WsT1xyrZqq684VPJzOF3hN5DNbowZ96Ie//PN0BtRW2\n" + 
// and so on 
     "-----END RSA PRIVATE KEY-----"; 

kann es einige mehr haben ‚\ n‘ verlassen, die in einigen unerwünschten Zeichen führen kann, wenn Sie generieren Keypec. Probieren Sie mehr System.out aus und sehen Sie, wie das codierte Byte-Array aussieht, und überprüfen Sie auch vorher priKeyPEM, ob ein zusätzliches Zeichen darin enthalten ist.

Hoffe, das hepls.

+1

Ich habe die Ausgabe von 'encoded' hochgeladen. http://pastebin.com/YusNdhgW. Ich habe auch den Test in eine reine Saite ohne '\ n' geändert und es hat auch nicht funktioniert. – Niklas

+0

Ich habe auch einen Screenshot mit der Ausgabe als String hochgeladen. – Niklas

+0

Base64-Decodierung ignoriert Zeilenumbrüche und normalerweise alle Leerzeichen. –

Verwandte Themen