AES Entschlüsselung teilweise fehlerhaft

Enfreyer

Mitglied
Hallo Leute!

Ich bin gerade dabei, mir einen Passwortmanager zu bauen. Dazu erzeuge ich ein XML Document,
welches dann in einen String umgewandelt wird. Dieser String wird mit einem gehashten Passwort
verschlüsselt und dann (binär) in einer Datei abgelegt.

Soweit zur Theorie ;).


Das Problem ist: Wenn ich die Datei entschlüssele, sind manche der Blöcke fehlerhaft entschlüsselt,
andere aber nicht.

In das Praxis sieht das so aus:

XML Document als String:
converted document: <?xml version="1.0" encoding="UTF-8" standalone="no"?><Quatsch><account id="1"><Account>Typ</Account><Password>hardt</Password></account></Quatsch>

Verschlüsselter XML String (Auszug):
É0¦˜8ÒäPeó^ÌØæ:W*Ë8×¾?)k¿.)pŒÉn±R1N3™ØÚ2&Ëë/\Šßh†íÄX…J È$µÎ+% Ö Jì .....

Entschlüsselter XML String:
<?xml version="1óÁ¥q«
:ø©xÓÄðP1F-8" standalone="no"?><Quatsch><account id="1"><Account>Typ</Account><Password>hardt</Password></account></Quatsch>

---

Da ich das ECB Chaining (vorerst) benutze, werden immer nur 16 Zeichen am Stück entschlüsselt.
Man erkennt hier, dass der zweite 16er Block falsch entschlüsselt wurde. Das treibt mich seit zwei
Tagen in den Wahnsinn...


Die Methoden sehen folgendermaßen aus:

Encryption + Save to File
Code:
	private static String encrypt(byte[] value, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, DecoderException, NoSuchProviderException {
		byte[] keyByteArray = org.apache.commons.codec.binary.Hex.decodeHex(key.toCharArray());
		SecretKeySpec skeySpec = new SecretKeySpec(keyByteArray, "AES");
		
		Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
		System.out.println(value.length);
		String encrypted = new String(cipher.doFinal(value));

		return encrypted;
	}



	public void writeToFile(String input) throws IOException, TransformerException {
		eraseFile();
		createFile();
	
		System.out.println("about to write1: " + input + "\n");
		
		FileOutputStream fos = new FileOutputStream(f);
		byte[] codeToWrite = input.getBytes();

		System.out.println("about to write len: " + codeToWrite.length + "\n");
		fos.write(codeToWrite);
		fos.close();

	}


Decryption
Code:
	public String getDecrypted() throws Exception {
		String result = "";
		byte[] encrypted = getEncryptedFromFile();

		if (encrypted!=null) {
			
			result = decrypt(encrypted, password);
		} 
		return result;
	}

	
	private byte[] getEncryptedFromFile() throws IOException {
		System.out.println("the username is: " +username);
		byte[] result = fa.readFile();
		System.out.println("read file lenght is: " + result.length + "\n");
		return result;	
	}


public byte[] readFile() throws IOException {
		FileInputStream fin = new FileInputStream(f);
		byte fileContent[] = new byte[(int)f.length()];
		fin.read(fileContent);
		fin.close();
	    return fileContent;
	}


	private static String decrypt(byte[] value, String key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, DecoderException, NoSuchProviderException {
		byte[] keyByteArray = org.apache.commons.codec.binary.Hex.decodeHex(key.toCharArray());
		SecretKeySpec skeySpec = new SecretKeySpec(keyByteArray, "AES");     
		
		Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
		cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		System.out.println("Length to decrypt: " + value.length);
		String originalMessage = new String(cipher.doFinal(value));
		
		System.out.println("Decrypted 2: " + originalMessage );
		return originalMessage;
	}


Ich habe auch schon so eine Vermutung. Ich glaube, dass bei der Kodierung der Zeichenfolgen
beim Speichern oder beim Lesen etwas schief läuft; also dass das Encoding aus der Datei nicht
mehr richtig gelesen wird und dadurch einzelne Zeichen falsch interpretiert werden. Das würde
erklären, warum nur manche Blöcke falsch entschlüsselt werden.

Ich habe auch schon mit dem BASE64 Encoder der Apache Codecs herumexperimentiert und
binäre Zeichenfolge in die Datei geschrieben. Das war aber mehr oder weniger Trial and Error
und hat zu keinem Ergebnis geführt. Ganz im Gegenteil sogar.

Hat jemand eine Idee?
 
Zuletzt bearbeitet:

Fab1

Top Contributor
ich stand mal vor dem gleichen Problem.

hab mir dann Methoden wie byteToString() stringToByte() geschrieben und immer nur diese Methoden verwendet um Strings "kurz" zu parsen. Hab den Code der Methoden leider nicht mehr.

Vielleicht schau ich später mal kurz über deinen Code drüber, momentan raucht mir aber noch zu sehr der Kopf.
 

Fab1

Top Contributor
Noch eine Frage: Kannst du denn einen Satz mit Umlauten entschlüsseln und verschlüsseln, bei dem dann immer das gleiche rauskommt? Also hackt es wirklich nur am schreiben/auslesen aus der Datei?


Nun ich hab nicht direkt einen Fehler gefunden, aber du kannst wenn du Lust hast mal folgendes versuchen. Ich hab jetzt mal die Methoden wie oben beschrieben eingebaut.

Java:
    import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
     
     
    public class Test {
     
       
        public static void main(String[] args) throws UnsupportedEncodingException {
           
        	String plainString = "Kühe dürfen nicht schnell laufen, damit sie ihre Milch nicht verschütten.";
        	System.out.println(plainString);
        	byte[] b= CryptHelper.stringToByte(plainString);
        	System.out.println(CryptHelper.byteToString(b));
        }
        
        private static String encrypt(byte[] value, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, UnsupportedEncodingException {
    		byte[] keyByteArray = CryptHelper.stringToByte(key);
    		SecretKeySpec skeySpec = new SecretKeySpec(keyByteArray, "AES");
    		
    		
    		Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    		System.out.println(value.length);
    		String encrypted = CryptHelper.byteToString(cipher.doFinal(value));

    		return encrypted;
    	}


    	private static String decrypt(byte[] value, String key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, NoSuchProviderException, UnsupportedEncodingException {
    		byte[] keyByteArray = CryptHelper.stringToByte(key);
    		SecretKeySpec skeySpec = new SecretKeySpec(keyByteArray, "AES");     
    		
    		Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    		cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    		System.out.println("Length to decrypt: " + value.length);
    		String originalMessage = CryptHelper.byteToString(cipher.doFinal(value));
    		
    		System.out.println("Decrypted 2: " + originalMessage );
    		return originalMessage;
    	}
           
    }

Java:
import java.io.UnsupportedEncodingException;


public class CryptHelper {

	

	public static String byteToString(byte[] b) throws UnsupportedEncodingException{
		
		String result = new String(b, "UTF-8");
		
		return result;
		
	}
	
	public static byte[] stringToByte(String s) throws UnsupportedEncodingException{
		
		byte [] result = s.getBytes("UTF-8");
		return result;
		
	}

}

Lass dich nicht von der Einfachheit der Lösungsvorschlages beeinflussen, denn genau solch kleiner "Unachtsamkeiten" können den Fehler verursachen.

Ansonsten kann ich dir den Tipp geben. Immer Stück für Stück vorzugehen. Nicht immer gleiche alles schreiben und erst dann testen, dann ist die Fehlerreichweite im Code sehr groß.
 

Enfreyer

Mitglied
Da haste natürlich recht ;).

Herzlichen Dank schon mal.

Also, wenn ich das frisch verschlüsselte Ergebnis direkt wieder entschlüssel, dann kommt
das richtige raus. Es muss also beim Lesen oder Schreiben aus/in die Datei passieren. Allerdings
steht in der Datei haargenau das, was die encrypt-Methode erzeugt. Und nach dem Auslesen
der Datei habe ich auch exakt diesen String wieder.

Nur wenn ich das Ergebnis vom encrypt direkt ans decrypt übergebe, funzt es.

Auch mit deinen Methoden ist es leider nicht anders.

Ich probier mal noch ein wenig rum und melde mich in Kürze nochmal ;).
 

Enfreyer

Mitglied
So. Ich habe zwar nicht die leiseste Ahnung, woran es lag, aber ich habe jetzt eine Lösung.
Habe diesen Part nochmal als separates Programm geschrieben, getrennt von dem ganzen XML
Rattenschwanz und den anderen Methoden.

Funktionsweise:
Einen String mit einem beliebigen Passwort mit AES (CBC Chaining und Padding) verschlüsseln.
Verschlüsselten String in eine Datei schreiben.
Verschlüsselten String aus derselben Datei lesen.
String wieder entschlüsseln.


Für alle, die vor demselben Problem stehen, hier die Lösung:

Code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;

public class Main {
	static String passwordAsHash;
	
	static String rawString; // zu verschlüsselnder Text
	static byte[] rawByte;

	static String encryptedString; // verschlüsselter Text
	static byte[] encryptedByte; 
	
	static String decryptedString; // entschlüsslter Text
	static byte[] decryptedByte; 
	
	
	public static void main(String[] args) throws NoSuchAlgorithmException, IOException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, DecoderException, InvalidKeyException {
		passwordAsHash = getHashFromString("totalSicheresPasswort");

		rawString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><Quatsch><account id=\"1\"><Account>Typ</Account><Password>hardt</Password></account></Quatsch>";
		rawByte = rawString.getBytes("UTF-8");
		System.out.println("String before encrypting: " + rawString + "\n");
		
		encryptedByte = encrypt(rawByte);
		encryptedString = new String(encryptedByte, "UTF-8");
		System.out.println("String before writing: " + encryptedString + "\n");

		writeByteToFile(encryptedByte);
		
		encryptedByte = readByteFromFile();
		encryptedString = new String(encryptedByte, "UTF-8");
		System.out.println("String after reading: " + encryptedString + "\n");
		
		decryptedByte = decrypt(encryptedByte);
		decryptedString = new String(decryptedByte, "UTF-8");
		System.out.println("String after decryption: " + decryptedString + "\n");
	}

	private static byte[] encrypt(byte[] in) throws DecoderException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
		byte[] keyByteArray = org.apache.commons.codec.binary.Hex.decodeHex(passwordAsHash.toCharArray());
		SecretKeySpec skeySpec = new SecretKeySpec(keyByteArray, "AES");
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
		return cipher.doFinal(in);
	}
	
	private static byte[] decrypt(byte[] in) throws InvalidKeyException, DecoderException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		byte[] keyByteArray = org.apache.commons.codec.binary.Hex.decodeHex(passwordAsHash.toCharArray());
		SecretKeySpec skeySpec = new SecretKeySpec(keyByteArray, "AES");
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		return cipher.doFinal(in);
	}
	
	private static byte[] readByteFromFile() throws IOException {
		File f = new File("theFile");
		FileInputStream is = new FileInputStream(f);
		byte[] result = new byte[(int)f.length()];
		is.read(result);
		is.close();
		return result;
	}

	private static void writeByteToFile(byte[] in) throws IOException {
		File f = new File("theFile");
		FileOutputStream out = new FileOutputStream(f);
		out.write(in);
		out.close();
	}
	
	private static String getHashFromString(String value) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		String result = "";
		MessageDigest dig = MessageDigest.getInstance("MD5");
		byte[] theHash = dig.digest(value.getBytes("UTF-8")); 
		StringBuilder sb = new StringBuilder(2*theHash.length); 
		for(byte b : theHash){ 
			sb.append(String.format("%02x", b&0xff));
		}
		result = sb.toString();
		return result;
	}
}
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Entschlüsselung Allgemeine Java-Themen 3
C Entschlüsselung schlägt fehl Allgemeine Java-Themen 1
D Java AES Ver- und Entschlüsselung Allgemeine Java-Themen 9
B Rot13 Entschlüsselung Allgemeine Java-Themen 7
V DES-Ver-/Entschlüsselung Allgemeine Java-Themen 9
R 128 Bit Verschlüsselung/Entschlüsselung in Java? Allgemeine Java-Themen 6
P Verschlüsselung in PHP -> Entschlüsselung in Java Allgemeine Java-Themen 2
T Passwortabfrage mit Entschlüsselung Allgemeine Java-Themen 4
B HeapSort für Array of Strings funktioniert nur teilweise Allgemeine Java-Themen 3
H Jar-Datei öffnet nur teilweise Allgemeine Java-Themen 2
E grundkurs-java.de: Applets funktionieren nur teilweise Allgemeine Java-Themen 3
T Gleiche Operation dauert teilweise sehr lange Allgemeine Java-Themen 12
A mit .equals Array befüllen schlägt teilweise fehl Allgemeine Java-Themen 3
Tobse Input/Output Datei Teilweise überschreiben Allgemeine Java-Themen 7
I Teilweise falsche Darstellung jap. Zeichen im JEditorPane mit RTFEditorKit aus RTF-Datei Allgemeine Java-Themen 5
3 Logger teilweise ausschalten Allgemeine Java-Themen 7
Junktyz In Writer und Outputstream wird teilweise nicht geschrieben Allgemeine Java-Themen 3
L Buffered Image teilweise zeichnen Allgemeine Java-Themen 6
B Long.parseLong löst teilweise Exception aus. Allgemeine Java-Themen 2
S meine java laufschrift funzt auf meinem NB teilweise schrott Allgemeine Java-Themen 2
Tommy Nightmare String.replaceAll(...) fehlerhaft? Allgemeine Java-Themen 3
K Eclipse compiled .Jar - Fehlerhaft? Allgemeine Java-Themen 2
P ObjectOutputStream oder ObjectInputStream fehlerhaft? Allgemeine Java-Themen 7
D Programm läuft fehlerhaft, finde den Fehler nicht Allgemeine Java-Themen 6
C Prüfen auf Zahl und 6 stellig fehlerhaft? warum? Allgemeine Java-Themen 7
K import- Anweisung fehlerhaft und andere Fehler (eclipse) Allgemeine Java-Themen 2
X Konsolenausgabe fehlerhaft Allgemeine Java-Themen 9
S Eclipse zeigt build.xml immer als fehlerhaft Allgemeine Java-Themen 12
D java.lang.Math fehlerhaft? Allgemeine Java-Themen 18

Ähnliche Java Themen

Neue Themen


Oben