AES Verschlüsselung - File Headers korrupt

SaschaSquare

Mitglied
Hallo Java'lers,

Vorweg: Ich bin Umsteiger von C# nach Java und setze mich gerade mit den alltäglichen Problemen auseinander.
Jetzt komme ich an einem bestimmtem Problem aber einfach nicht weiter. Es geht um Verschlüsselung mit AES.

Folgender Ablauf:
Ich verschlüssel eine Datei (z.B. jpg/pdf) mit Hilfe von der Cipher Klasse und einem AES Key. -> Funktioniert (denke ich)
Wenn ich die Datei allerdings wieder entschlüssel, bekomme ich eine kaputte Datei zurück.
Bei einem Bild sagt Windows beispielsweise es sei defekt...
Ich habe beide Dateien (original und wieder-entschlüsselte) in einem Editor geöffnet und miteinander verglichen. Und folgendes festgestellt (dies gilt übrigens nicht nur bei Bild-Dateien sondern auch bei beispielsweise PDF-Dateien).

Die ersten paar Bytes (im Header der Datei) stimmen komplett nicht überein und sind sogar unterschiedlich lang. Überschreibe ich die entsprechenden Bytes in dem wieder-entschlüsselte File mit den originalen Bytes und speicher dieses File ab, so lässt sich das Bild/PDF einwandfrei öffnen.

Mir stellt sich nun natürlich die Frage, wieso die ersten paar Bytes jeder Datei nach dem Verschlüsseln/Entschlüsseln unterschiedlich sind !?

Zum Debuggen habe ich bereits überprüft ob es an der Art des Lesens/Schreibens liegt, aber dabei fiel kein Fehler auf (die Datei wurde erfolgreich 'kopiert')...

Zur Verdeutlichung hier etwas Code:

Ich danke schon mal im voraus für Bemühungen :)

GenerateKey()
Erzeugt den AES Key der später zur Ver-/Entschlüsselung verwendet wird.
Java:
// GLOBAL
public String CryptMode = "AES/CBC/PKCS7Padding";

public void GenerateKey() {
		KeyGenerator keyGen;
		try {
			
			SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
			char[] password = {'a', 'b', 'c'};						
			byte[] salt = SecureRandom.getSeed(8);			
			KeySpec spec = new PBEKeySpec(password, salt, 8, 256);			
			SecretKey tmp = factory.generateSecret(spec);			
			this.secret = new SecretKeySpec(tmp.getEncoded(), "AES");			
			
			final Cipher cipher = Cipher.getInstance(this.CryptMode);
			//final Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
			cipher.init(Cipher.ENCRYPT_MODE, this.secret);
			
			AlgorithmParameters params = cipher.getParameters();
			iv = params.getParameterSpec(IvParameterSpec.class).getIV();
			
		}
		catch (Exception ex) {
			LogToScreen(ex.getMessage());
		}
	}


Encrypt()
Diese Methode verschlüsselt die Übergebene Datei und legt sie unter einem neuen Dateinamen ab
Java:
public void Encrypt(String srcName, String destName) {
    	File path = Environment.getExternalStorageDirectory();
    	File file = new File(path, destName);  
    	
    	File fileinput = new File(path, srcName); 
    	    	    
    	if (path.canWrite()) {    		
    		try {				
    			final Cipher cipher = Cipher.getInstance(this.CryptMode);
    			cipher.init(Cipher.ENCRYPT_MODE, this.secret);
    			    			    			
    			final FileOutputStream fos  = new FileOutputStream(file);
    			final BufferedOutputStream bos = new BufferedOutputStream(fos);

    			final FileInputStream fis = new FileInputStream(fileinput);
    			final BufferedInputStream bis = new BufferedInputStream(fis); // ADDED
    			
    			byte[] bin = new byte[bis.available()];
    			bis.read(bin, 0, bin.length);
    			bos.write(cipher.doFinal(bin));
    			
    			bis.close();
    			fis.close();
    			
    			bos.flush();    			
    			bos.close();    			
			} catch (Exception e) { 
				e.printStackTrace();
				LogToScreen("Encrypt:" + e.getMessage());
			}    	
    	}
    	else {
    		LogToScreen("CanWrite = FALSE");
    	}
    }

Decrypt()
Entschlüsselt die Übergebene Datei und legt sie unter einem neuen Dateinamen ab
Java:
public void Decrypt(String srcName, String destName) {
    	File path = Environment.getExternalStorageDirectory();
    	File file = new File(path, srcName);
    	
    	File fileoutput = new File(path, destName);
        
        try {			        	
        	final Cipher cipher = Cipher.getInstance(this.CryptMode);
			cipher.init(Cipher.DECRYPT_MODE, this.secret, new IvParameterSpec(this.iv));
										
			final FileInputStream fis  = new FileInputStream(file);
			final BufferedInputStream bis = new BufferedInputStream(fis);
			
			byte[] btest = new byte[bis.available()];			
			bis.read(btest, 0, btest.length);
			
			final FileOutputStream fwrite = new FileOutputStream(fileoutput);
			final BufferedOutputStream bwrite = new BufferedOutputStream(fwrite);
			
			bwrite.write(cipher.doFinal(btest));
			bwrite.flush();
			bwrite.close();
			fwrite.close();
			
			
		} catch (Exception e) {
			e.printStackTrace();
			LogToScreen("Decrypt:" + e.getMessage());
		}        
    }


Mit freundlichen Grüßen
SaschaSquare
 
Zuletzt bearbeitet:

HoaX

Top Contributor
Mal die Dateigrößen verglichen? Ich vermute stark dass wegen
Java:
byte[] bin = new byte[bis.available()];
nicht die komplette Datei gelesen wird.
 

SaschaSquare

Mitglied
Die Dateigrößen der originalen Datei und der wieder-entschlüsselten Datei sind identisch.
Einzig die verschlüsselte Datei hat eine andere größe, was aber meiner Meinung nach sein kann.

Ein Diff-Vergleich mit einem Editor der beiden Dateien zeigt auch, dass in dem wieder-entschlüsselten im Header a) zu viele Zeichen sind und b) bis zu einem gewissen Punkt auch falsche Zeichen.

Kopiere ich die Zeichen aus dem Originalen und überschreibe damit die falschen Zeichen, ist die Datei auch korrekt und lässt sich öffnen...
 

SaschaSquare

Mitglied
Ebenius: Ich habe den Debugger gerade mal an der Zeile 15 mit dem Read angehalten.
Ich bekomme als Rückgabe der Methode ein -1 zurück was mir laut der API Doc sagt, dass ich den Stream komplett "ausgelesen" habe und nichts mehr übrig ist zum Lesen -> Korrekt?!

Das Problem scheint ja zu sein, dass ich nicht zu wenig auslese sondern anscheinend a) zu viel und b) etwas falsches...
 

Ebenius

Top Contributor
Hm. In Deinem Code-Beispiel oben heißt [c]-1[/c] konkret, dass Du genau gar nichts gelesen hast. Daraus sollte folgen, dass 1. [c]btest[/c] null-lang ist und 2. die Datei eine Nullänge haben sollte. Oder hab ich ne Schleife überlesen?

Sehr sonderbar.

Ebenius
 

SaschaSquare

Mitglied
Wenn ich von der Read() Methode ein -1 zurück bekomme, heißt das laut der API Docu das ich den Stream "bis zum Ende" ausgelesen habe.
Der Debugger zeigt anschließen bei .available() eine 0 an was mich eigentlich darin bestätigt dass ich den Stream komplett gelesen habe.

Bei der Entschlüsselung habe ich nun auch mal den Rückgabewert der Read() Methode ausgewertet und diese zeigt mir kein -1 sondern die Anzahl Bytes die die Datei auch wirklich groß ist.
Heißt das nun dass ich den Stream nicht vollständig gelesen habe weil ich kein -1 zurück bekommen habe?

Und das verwirrende ist ja, dass ich in meiner wieder-entschlüsselten Datei nicht zu wenig Bytes habe, sondern zu viele...
 

Ebenius

Top Contributor
Achso, Du bezogst Dich auf die encrypt-Methode. Ich dachte Du bekommst in Decrypt eine [c]-1[/c] in Zeile 15 (oben).

Ohne mich mit JCE wirklich auszukennen, sollte Dein Decrypt-Code mit Standard I/O meiner Meinung nach in etwa (Achtung: Code im Browser getippt) so aussehen:
Java:
public void decrypt(String srcName, String destName) {
        File path = Environment.getExternalStorageDirectory();
        File file = new File(path, srcName);
        
        File fileoutput = new File(path, destName);
        
        try {                       
            final Cipher cipher = Cipher.getInstance(this.CryptMode);
            cipher.init(Cipher.DECRYPT_MODE, this.secret, new IvParameterSpec(this.iv));
                                        
            final FileInputStream fis  = new FileInputStream(file);
            final BufferedInputStream bis = new BufferedInputStream(fis);
            final FileOutputStream fwrite = new FileOutputStream(fileoutput);
            final BufferedOutputStream bwrite = new BufferedOutputStream(fwrite);
            final CipherOutputStream ciphwrite = new CipherOutputStream(bwrite, cipher);

            final byte[] arr = new byte[1024];
            int bytesRead;
            while((bytesRead = bis.read(arr, 0, arr.length)) != -1) {
                ciphwrite.write(arr, 0, bytesRead); // write read bytes from buffer to cipher output stream
            }
 
            cyphwrite.flush(); // flushes underlying streams as well; implicitly done in close() since JRE 6
            cyphwrite.close(); // closes underlying streams as well; calls doFinal on the cipher instance
        } catch (Exception e) {
            e.printStackTrace();
            LogToScreen("Decrypt:" + e.getMessage());
        }        
    }

Encrypt hab ich mir nicht angesehen; sollte aber aus meinem Code-Schnipsel einfach herleitbar sein.

Gleich mal zum Naming: In Java alle Methoden und Variablen mit kleinem Buchstaben vorn: [c]doSomething(someVariable)[/c].

HTH, Ebenius
 

SaschaSquare

Mitglied
Ich werde jetzt mal nach Hause fahren und etwas Essen, anschließend begebe ich mich noch mal an das Problem und versuche es auf deine Art.

Schon mal vielen Dank für die Unterstützung, sobald ich heute Abend was habe melde ich mich nochmal.
Und gegebenenfalls einen schönen Abend noch ;)


MfG
SaschaSquare
 

Andi_CH

Top Contributor
Ohne alles zu analysieren - nimm doch zwischen lesen und schreiben die kryptologie raus - die geschrieben Datei sollte dann ja verwendbar sein. So kannst du prüfen ob der Fehler in den Lese- Schreibloops oder in der Kryptologie steckt.
 

SaschaSquare

Mitglied
Ja ich habe die Kryptographie bereits entfernt gehabt und das Lesen/Schreiben auf die selbe Weiße versucht und die Datei wurde vollständig und korrekt "kopiert".

Mich wundert es eben, dass nicht die gesamte Datei nach einem Verschlüsseln/Entschlüsseln defekt ist, sondern eben nur der Header bzw. die ersten Bytes einer Datei davon betroffen sind...

-- -- EDIT -- --

Ich habe im Anhang mal ein Bild angehangen was den Unterschied der beiden Dateien verdeutlicht.
Die obere Zeile ist das originale Bild.
Die untere Zeile hingegen ist das wieder-entschlüsselte Bild welches von Windows nicht mehr angezeigt werden kann.
Es sind jeweils die ersten Bytes der Datei welche sich ab dem roten Strich nicht mehr unterscheiden. Kopiere ich aus der ersten Zeile ab dem roten Strich bis zum Ende nach links und füge das in die untere Zeile ein und speichere, ist das Bild anschließend korrekt darstellbar.

Es sind also wirklich nur die ersten paar Bytes der Datei welche "defekt" sind.

Ich habe überhaupt keine Ahnung mehr woran das liegen könnte...


-- -- EDIT -- --


Das Problem ist gelöst!
Es lag daran, dass wir zwar den CBC (Cipher Block Chaining Mode) genutzt hatten, den IV (Initialisierungsvektor) allerdings beim Entschlüsseln nicht beim cipher.init() übergeben hatten.
Letztendlich also ein dummer Fehler...

Für jemanden mit dem selben Problem, hier ein interessanter Link zum IV: Initialisierungsvektor ? Wikipedia

Dennoch vielen vielen Dank für eure Mühe mir zu helfen! :toll:
 

Anhänge

  • corruptedHeader.png
    corruptedHeader.png
    3,8 KB · Aufrufe: 28
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
M pfx-Zertifikat in Tomcat für SSL-Verschlüsselung nutzen Allgemeine Java-Themen 14
X Verschlüsselung Allgemeine Java-Themen 18
P String-Verschlüsselung - Frage zur Sicherheit Allgemeine Java-Themen 21
R Verschlüsselung falsch Allgemeine Java-Themen 3
R Verschlüsselung funktioniert nicht Allgemeine Java-Themen 5
J Passwort Verschlüsselung hash Allgemeine Java-Themen 2
D AES Verschlüsselung / Wirklich AES 128-Bit? Allgemeine Java-Themen 4
I Best Practice Verschlüsselung mit SALT Allgemeine Java-Themen 4
A Mehrfache XOR Verschlüsselung Allgemeine Java-Themen 11
Thallius Moderne sichere synchrone Verschlüsselung mit Java? Allgemeine Java-Themen 3
Ananaskirsche Verschlüsselung mit AES Allgemeine Java-Themen 4
E Verschlüsselung Allgemeine Java-Themen 4
F Schlüsselworte RSA Verschlüsselung implementieren Allgemeine Java-Themen 5
S Key (für AES-Verschlüsselung) aus String Allgemeine Java-Themen 4
M Serialisierung & Verschlüsselung Allgemeine Java-Themen 2
K Problem mit Salted - Verschlüsselung Allgemeine Java-Themen 4
Z Java E-Mail Client mit End-to-End-Verschlüsselung Allgemeine Java-Themen 4
J Verschlüsselung von Text? Allgemeine Java-Themen 2
K Vigenere- Verschlüsselung Allgemeine Java-Themen 13
M Verschlüsselung von Text und Files durch RSA (Encoding Problem) Allgemeine Java-Themen 7
T AES-Verschlüsselung mit eigenem 256 Bit Schlüssel Allgemeine Java-Themen 12
DStrohma Verschlüsselung: SALT aus Passwort generieren? Allgemeine Java-Themen 3
G AES Verschlüsselung nur bis 63 Zeichen Länge Allgemeine Java-Themen 2
M Verschlüsselung mit Cipher Allgemeine Java-Themen 5
B XOR Verschlüsselung Allgemeine Java-Themen 7
S Framework für symetrische und asymetrische Verschlüsselung Allgemeine Java-Themen 3
lumo Verschlüsselung Allgemeine Java-Themen 2
H Verschlüsselung mit Blowfish Allgemeine Java-Themen 14
C Interpreter-Fehler AES verschlüsselung mit MD5 key Allgemeine Java-Themen 6
A Datei, UTF-8, NTRU-Verschlüsselung Allgemeine Java-Themen 3
B "Verschlüsselung" mit Passwort (XOR bzw. Modulo) Allgemeine Java-Themen 7
B String Verschlüsselung Allgemeine Java-Themen 6
M Verschlüsselung anwenden Allgemeine Java-Themen 6
J Verschlüsselung Allgemeine Java-Themen 22
T MD5 Verschlüsselung Nullen fehlen? Allgemeine Java-Themen 2
L [Exception] RSA Verschlüsselung. Allgemeine Java-Themen 16
C javamail signatur und verschlüsselung Allgemeine Java-Themen 2
R 128 Bit Verschlüsselung/Entschlüsselung in Java? Allgemeine Java-Themen 6
F RSA-Verschlüsselung Allgemeine Java-Themen 4
S Verschlüsselung in Java Allgemeine Java-Themen 2
G Interessant! Verschlüsselung in Java, Charset in der JVM? Allgemeine Java-Themen 14
D Eigener Key bei AES Verschlüsselung Allgemeine Java-Themen 4
T Verschlüsselung von Dateien Allgemeine Java-Themen 8
S Verschlüsselung - IllegalBlockSizeException Allgemeine Java-Themen 3
G Problem mit RSA Verschlüsselung bei .net und Java Allgemeine Java-Themen 1
D Caesar und Vigenère Verschlüsselung Allgemeine Java-Themen 2
alexpetri Verschlüsselung Allgemeine Java-Themen 13
@ [Sicherheit] Speicherung von Keys für Verschlüsselung Allgemeine Java-Themen 4
P Verschlüsselung in PHP -> Entschlüsselung in Java Allgemeine Java-Themen 2
Lazybone Caeser Verschlüsselung Allgemeine Java-Themen 6
S Verschlüsselung mit Cipher Allgemeine Java-Themen 8
S Verschlüsselung Allgemeine Java-Themen 15
J Problem mit Dateien/XOR-Verschlüsselung Allgemeine Java-Themen 5
G RSA-Verschlüsselung Allgemeine Java-Themen 1
P HMACMD5- Verschlüsselung entschlüsseln Allgemeine Java-Themen 2
I Verschlüsselung mit Pwd. - User soll Algorithmus wählen Allgemeine Java-Themen 4
J Probleme bei XOR verschlüsselung ! Allgemeine Java-Themen 5
G Verschlüsselung in Java Allgemeine Java-Themen 9
M RSA Verschlüsselung Allgemeine Java-Themen 7
J Verschlüsselung von Daten Allgemeine Java-Themen 21
H "File too large" - genauere IOException-Behandlung Allgemeine Java-Themen 5
H Sicherer File Tresor Allgemeine Java-Themen 13
W Jar-File Start nur über Terminal Allgemeine Java-Themen 13
R 11 GB File lesen ohne zu extrahieren Filedaten Bereich für Bereich adressieren dann mit Multi-Thread id die DB importieren Allgemeine Java-Themen 3
D Read JSON File Problem Allgemeine Java-Themen 9
S Umstellung von File auf Path - Probleme mit Stream Allgemeine Java-Themen 5
C jar File mehrfach aufrufen (als Windows Dienst) Allgemeine Java-Themen 5
N File Path mit Variablen angeben Allgemeine Java-Themen 1
izoards Zugriff auf gemeinsame Ressource (CSV-File) Allgemeine Java-Themen 3
S Class File Editor -> Source not found Allgemeine Java-Themen 4
F jar File ausführen Allgemeine Java-Themen 14
M File Binary Representation Allgemeine Java-Themen 1
N jar File auf Mac mit Doppelklick starten Allgemeine Java-Themen 5
O Input/Output java.io.File beenden Allgemeine Java-Themen 5
G File not found - nach dem Kompilieren Allgemeine Java-Themen 6
T Jar File zu exe... Allgemeine Java-Themen 3
M Foreign Memory API / Memory-Mapped File Allgemeine Java-Themen 0
R Delete files before creating new from temp using Java file method Allgemeine Java-Themen 1
S File lesen und schreiben Java 6 Allgemeine Java-Themen 2
T String-Manipulation beim Ablauf in Eclipse und als JAR-File Allgemeine Java-Themen 8
F Input/Output FileNotFoundException, obwohl File existiert Allgemeine Java-Themen 5
G Excel File öffnen, in Zelle schreiben, abspeichern Allgemeine Java-Themen 6
L JAR-File auf Ilias (LMS) laufen lassen Allgemeine Java-Themen 0
ralfb1105 Classpath Directory fuer Properties File Allgemeine Java-Themen 2
L File beim Kopieren in einen anderen Ordner umbenennen Allgemeine Java-Themen 6
J File in Package erstellen & lesen mit Programmstart in externe Projekt Allgemeine Java-Themen 3
I File ausführen und mein Programm bearbeiten lassen Allgemeine Java-Themen 11
A File lesen Codierung Charset Allgemeine Java-Themen 5
J .java-Dateitext Compile zur Laufzeit ohne File Allgemeine Java-Themen 15
M Key-File im selben Ordner speichern? Allgemeine Java-Themen 18
I TrueZip add file to archive Allgemeine Java-Themen 10
T Probleme mit dem Pfad zum Propertie file Allgemeine Java-Themen 7
J ftp - delete file ohne appache Allgemeine Java-Themen 8
X Klassen File-Klasse wird als Directory markiert Allgemeine Java-Themen 8
T ImageIO.read -> Can`t read input file Allgemeine Java-Themen 11
L Applet Problem "security: Trusted libraries list file not found" ? Allgemeine Java-Themen 7
C Swing File[] als klickbare links in irgendeinem Swing Element Allgemeine Java-Themen 3
H Kennt sich jemand mit Eclipse und dem Thema Jar-File aus ? Allgemeine Java-Themen 6
H Laden einer (Resourcendatei) aus einem Jar-File Allgemeine Java-Themen 17
C Authentifizierung mit java.nio.file? Allgemeine Java-Themen 5

Ähnliche Java Themen


Oben