2014-02-06 20 views
8
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
kpg.initialize(1024); 
KeyPair kp = kpg.genKeyPair(); 
Key publicKey = kp.getPublic(); 
Key privateKey = kp.getPrivate(); 

Ich möchte nur den öffentlichen Schlüssel aus einer byte[] erstellen.Serialisieren und Deserialisieren eines öffentlichen RSA-Schlüssels

Ich habe versucht, dies als Experiment:

publicKey = new SecretKeySpec(publicKey.getEncoded(), publicKey.getAlgorithm()); 

Aber Entschlüsselung dass Schlüssel dann fehl.

Ich habe auch versucht, den Schlüssel mit ObjectOutputStream serialisieren, aber Serialisierung schlägt fehl.

java.io.NotSerializableException: org.apache.harmony.xnet.provider.jsse.OpenSSLKey

Ich las here, dass ich nicht SecretKeySpec mit RSA verwenden können.

Wenn Sie also von einem SecretKey und nicht von einem RSA- oder DSA-Schlüssel sprechen, müssen Sie keine Verdrehungen mit KeyGenerator oder ähnlichem durchführen.

Wer weiß, wie man diese Verrenkungen durchführt oder wie man das macht.

+0

Für RSA gibt es [RSAPrivateKeySpec] (https://docs.oracle.com/javase/7/docs/api/java/security/spec/RSAPrivateKeySpec.html) – tuxayo

+0

@tuxayo Ja, das ist in einer Antwort unten bereits . – weston

+0

Wo?Ich sehe nur Erwähnungen von PKCS8EncodedKeySpec. Wie auch immer ich konnte nicht RSAPrivateKeySpec arbeiten und endete mit PKCS8EncodedKeySpec. Soll ich meinen ersten Kommentar löschen, der irreführend sein kann? – tuxayo

Antwort

4

Asymmetrische Schlüssel wie die von RSA werden normalerweise im X509-Format gespeichert. Daher können Sie stattdessen X509EncodedKeySpec verwenden.

Ein einfaches Beispiel ist bereits in der Java 7 JavaDoc (nur ersetzen DSA mit RSA): http://docs.oracle.com/javase/7/docs/api/java/security/KeyFactory.html

X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey); 
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec); 

Wenn Sie das privat von byte[] deserialisieren brauchen, ich habe festgestellt, dass Sie PKCS8EncodedKeySpec verwenden müssen .

0

Ich verwende den folgenden Code ein PubliKey PEM Format Base64

String publicKeyString = javax.xml.bind.DatatypeConverter.printBase64Binary(publicKey.getEncoded()); 

ich es hilft hoffen, zu konvertieren.

+1

Wie können Sie aus dem Bytearray den ursprünglichen Schlüssel wiederherstellen? – Alexey

5

Hängt davon ab, was Sie mit der serialisierten Darstellung machen möchten. Wenn der Verbraucher niemand anderes als Ihr eigenes Programm ist, können Sie Ihre eigene Implementierung erstellen. Ein öffentlicher RSA-Schlüssel besteht aus zwei ganzen Zahlen - Exponent und Modul. Der Modul ist groß - etwa 1024 Bits, der Exponent liegt typischerweise in der Größenordnung von 17 Bits. Beide Objekte sind als BigInteger-Objekte verfügbar, wenn Sie Ihr öffentliches Schlüsselobjekt auf RSAPublicKey umwandeln.

So rekapitulieren:

RSAPublicKey publicKey = (RSAPublicKey)kp.getPublic(); 
return publicKey.getModulus().toString() + "|" + 
    publicKey.getPublicExponent().toString(); 

, dass ausreichend ist, den Schlüssel wiederherzustellen. Deserialisieren:

String []Parts = MyKeyString.split("\\|"); 
RSAPublicKeySpec Spec = new RSAPublicKeySpec(
     new BigInteger(Parts[0]), 
     new BigInteger(Parts[1])); 
return KeyFactory.getInstance("RSA").generatePublic(Spec); 

Wenn die wichtigsten Anforderungen an Software von Drittanbietern weitergegeben werden, sollten Sie besser Serialisierung in einem Standardformat - PEM oder DEN.

+0

Schöne Option, hilft zu verstehen, was los ist, aber 'getEncoded()' und die 'X509EncodedKeySpec' für die Deserialisierung sind genug für mich. – weston

Verwandte Themen