PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java Cryptography Architecture/Extension


#44
2010-12-09, 21:47:47
Ich habe so meine Probleme mit der JCA... Vlt. hat jmd. von euch mehr Ahnung (meine Kentnisse über Kryptographie sind eher rudimentär) bzw. sieht was, was ich gerade nicht sehe.
Lief meines erachtens nach einwandfrei.
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (kpg != null) {
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
FileOutputStream fospu = new FileOutputStream("./public.key");
FileOutputStream fospr = new FileOutputStream("./private.key");
ObjectOutputStream oospu = new ObjectOutputStream(fospu);
ObjectOutputStream oospr = new ObjectOutputStream(fospr);
oospu.writeObject(publicKey);
oospr.writeObject(privateKey);
oospu.flush();
oospu.close();
oospr.flush();
oospr.close();
fospu.flush();
fospu.close();
fospr.flush();
fospr.close();
}

Läuft auch problemlos: try {
FileInputStream fispr = new FileInputStream("./private.key");
ObjectInputStream oispr = new ObjectInputStream(fispr);
Key prk = (Key) oispr.readObject();
oispr.close();
fispr.close();
FileInputStream fispu = new FileInputStream("./public.key");
ObjectInputStream oispu = new ObjectInputStream(fispu);
Key puk = (Key) oispu.readObject();
oispu.close();
fispu.close();

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, puk);

System.out.println(new String("test".getBytes()));

byte[] verschlüsselt = cipher.doFinal("test".getBytes());
System.out.println(new String(verschlüsselt));
cipher.init(Cipher.DECRYPT_MODE, prk);
byte[] entschlüsselt = cipher.doFinal(verschlüsselt);
System.out.println(new String(entschlüsselt));
} catch (Exception ex) {
ex.printStackTrace();
}

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;

public class Crypto {
private static Key publicKey, privateKey;
private static Cipher cipher;

public static String encrypt(String str) {
String result = "";

if (publicKey == null) {
try {
FileInputStream fis = new FileInputStream("./public.key");
ObjectInputStream ois = new ObjectInputStream(fis);
publicKey = (Key) ois.readObject();
ois.close();
fis.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}

initCipher();

try {
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = new String(cipher.doFinal(str.getBytes()));
System.out.println(result);
} catch (Exception ex) {
ex.printStackTrace();
}

return result;
}

public static String decrypt(String str) {
String result = "";

if (privateKey == null) {
try {
FileInputStream fis = new FileInputStream("./private.key");
ObjectInputStream ois = new ObjectInputStream(fis);
privateKey = (Key) ois.readObject();
ois.close();
fis.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}

initCipher();

try {
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = new String(cipher.doFinal(str.getBytes()));
} catch (Exception ex) {
ex.printStackTrace();
}

return result;
}

private static void initCipher() {
if (cipher == null) {
try {
cipher = Cipher.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
}
}
Hier fangen jetzt die Probleme an. Ich bekomme immer eine Exception wenn ich folgenden Code ausführe:
System.out.println(Crypto.decrypt(Crypto.encrypt("test")));
Beim cipher.doFinal() in decrypt kommt:
javax.crypto.BadPaddingException: Data must start with zero

Was mir ausserdem aufgefallen ist: Der Ciphertext ist bei jedem Ausführen ein anderer, es wird also scheinbar noch ein zusätzlicher Zufall verwurstet. Da bekomme ich doch Probleme, wenn das später irgendwann mal entschlüsselt werden soll, oder?

#44
2010-12-10, 10:33:04
As usual care should be taken if you're using the getBytes() method on String objects. You should always be specifying the encoding to be used. This can easily bite you when encrypting on one platform and decrypting on another. (http://stackoverflow.com/questions/295436/java-jce-decrypting-long-message-encrypted-with-rsa)
Scheinbar auch nicht ganz problemlos auf dem selben PC, wenn man Strings wiederherstellt indem man ihnen die Bytes im Konstruktor mitgibt... :redface:

Das mit den unterschiedlichen Ciphertexten ist aber weiterhin so. Muss mal ausprobieren, ob sich das problemlos mit einer anderen Cipher-Instanz wieder entschlüsseln lässt...

Mdk
2010-12-10, 12:24:21
Ohne JCA aktiv verwendet zu haben, verwendet die OAEP? Dann erklärt das die unterschiedlichen Ciphertexte...

mfg
mdk