Java: AES / RSA Keys lesen und schreiben (Datei)

Java VerschlüsselungGestern Vormittag hat Bastian, ein AxxG Blog Leser, einen sehr interessanten Kommentar unter meinen Beitrag „Java: Verschlüsselung mit Beispiel (Quickstart)“ hinterlassen. Darin fragt er, wie man einen Schlüssel einer AES- oder RSA-Verschlüsselung sichern bzw. für andere Systeme verwenden kann.
Da die Antwort sehr umfangreich wurde, habe ich mich kurzerhand dazu entschlossen einen Beitrag, zu diesem Thema, zu verfassen.

 

AES Key in eine Datei schreiben

Als erstes ist es wichtig seinen genertierten oder erstellten Key zu speichern.

// Datei
File datei = new File("AES.key");

// zufaelligen Key erzeugen
KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(128);
Key key = keygen.generateKey();

// Key in die Datei schreiben
byte[] bytes = key.getEncoded();
FileOutputStream keyfos = new FileOutputStream(datei);
keyfos.write(bytes);
keyfos.close();

 

RSA Keys in zwei Dateien schreiben

Etwas komplizierter geht es bei RSA:

// Datei
File dir = new File("keys");

// Verzeichnis anlegen
dir.mkdirs();

// zufaelligen Key erzeugen
KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
keygen.initialize(1024);
KeyPair keyPair = keygen.genKeyPair();

// schluessel lesen
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

// Public Key sichern
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(dir.getAbsoluteFile() + "/public.key");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();

// Private Key sichern
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
fos = new FileOutputStream(dir.getAbsoluteFile() + "/private.key");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();

 

Wechsel

 

AES Key aus einer Datei lesen

// Datei
File datei = new File("AES.key");

// Key lesen
FileInputStream fis = new FileInputStream(datei);
byte[] encodedKey = new byte[(int) datei.length()];
fis.read(encodedKey);
fis.close();
		
// generiere Key
SecretKey key = new SecretKeySpec(encodedKey, "AES");		

 

RSA Keys auslesen

//+++++++++++++++++++++++++++++++++
// Private key
//+++++++++++++++++++++++++++++++++
// Datei
File dateiPriK = new File("keys/private.key");

// Private Key lesen
FileInputStream fis = new FileInputStream(dateiPriK);
byte[] encodedPrivateKey = new byte[(int) dateiPriK.length()];
fis.read(encodedPrivateKey);
fis.close();
		
// generiere Key
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);	

//+++++++++++++++++++++++++++++++++
// Public key
//+++++++++++++++++++++++++++++++++
// Datei
File dateiPubK = new File("keys/public.key");

// Public key lesen
fis = new FileInputStream(dateiPubK);
byte[] encodedPublicKey = new byte[(int) dateiPubK.length()];
fis.read(encodedPublicKey);
fis.close();
		
// generiere Key
keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

 

Antwort zu der Frage

Wie du sehen kannst, gibt es verschiedene Arten Keys in einer Datei zu speichern. Noch mal zusammengefasst:

Mit der Datei(der Key) und dem Wissen, welche Kodierung verwendet wurde, kann man die Verschlüsselung auf anderen Systemen oder in einer anderen Programmiersprache einsetzen. Oftmals bieten die Programmiersprachen schon Klassen zum einlesen des Keys an. Andere wiederum verlangen das Konvertieren des Key’s in ein anderes Format. Wie zum Beispiel PHP:

	function pkcs8_to_pem($der) {

	    static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----";
	    static $END_MARKER = "-----END PRIVATE KEY-----";

	    $value = base64_encode($der);

	    $pem = $BEGIN_MARKER . "\n";
	    $pem .= chunk_split($value, 64, "\n");
	    $pem .= $END_MARKER . "\n";

	    return $pem;

 

	function x509_to_pem($der) {

	    static $BEGIN_MARKER = "-----BEGIN PUBLIC KEY-----";
	    static $END_MARKER = "-----END PUBLIC KEY-----";

	    $value = base64_encode($der);

	    $pem = $BEGIN_MARKER . "\n";
	    $pem .= chunk_split($value, 64, "\n");
	    $pem .= $END_MARKER . "\n";

	    return $pem;

Diese brauch den Key als PEM BASE64 verschlüsselt. Andere Programmiersprachen brauchen ggf. andere Formate, je nach Anwendungsfall.
Ich hoffe, dass ich damit deine Frage beantworten konnte:-)

 

Die Quellen

 

Copyright © 2013 AxxG – Alexander Gräsel



3 Antworten : “Java: AES / RSA Keys lesen und schreiben (Datei)”

  1. Endless Storm sagt:

    Hallo,

    wie sieht das eigentlich aus, wenn ich auf dem Smartphone soeine Verschlüsselung einsetzen will. Wie sicher ist es, wenn ich die Dateien mit den Schlüsseln auf dem Smartphone liegen habe?
    Wenn jemand diese Schlüssel-Daten klaut, kann er damit Nachrichten von mir entschlüsseln? Wenn ja, gibt es eine Möglichkeit, sich davor zu schützen?

    Ansonsten vielen Dank für diese Tolle Einführung!

    • Hallo du,
      auf jedem Endgerät hast du das Problem, was du da beschrieben hast. Aber wie immer gilt auch hier die 80-20-Regel. D.h. wenn du den Schlüssel nicht auf der SD-Karte ablegst, sondern in einer anwendungsspezifischen Datenbank als String speicherst und das Feld zusätzlich per IMEI symmetrisch verschlüsselt, hältst du ca. 80 % der Bösewichte auf.
      Die restlichen 20% wird schwierig….

      • c0d3d3v sagt:

        Hört sich für mich nicht viel sicherer an den Schlüssel mit der IMEI zu verschlüsseln. Meiner Meinung wäre ein zusätzliches Kennwort das der Benutzer eingeben kann eine Sicherheitserweiterung. Das Kennwort würde dazu dienen die Datenbank zu symetrisch entschlüsseln/verschlüsselen.

Kommentar verfassen