Cipher(In)OutputStream

Status
Nicht offen für weitere Antworten.

dafrog

Neues Mitglied
Tach Zusammen,

habe mal (wieder) angefangen ein bisschen Java zu lernen. Bin irgendwie an der "cipher Klasse" vorbeigekommen. Hab mir gedacht probier doch mal Dateien und Konsoleneingaben zu (de)encrypten. Wenn ich mich mal in ein Thema hineingesteigert habe komm ich nicht mehr los bis es klappt . Moeglicherweise bin ich auf dem Holzweg?!
Naja eigendlich ist das ja kein Thema fuer einen "Einsteiger" wie mich aber vielleicht hat ja jemand trotzdem eine Idee wie ich die folgenden Probleme loesen kann.

Danke schon mal an jeden der sich die Zeit nimmt.
Gruss
Fabian

Probleme:
1. Konsoleneingaben (Methoden encryptInput, decryptInput) werden bei Entschluesslungen abgeschnitten (siehe Code 2 Beispiel)
2. Bei Dateiverschluesselungen (Methoden encryptFile, decryptFile) werden z.B. Bilder/Dokumente unlesbar. Ich denke das da irgendwie falsche Zeichen ausgegeben werden.

Code:
import java.io.*;
import java.security.Key;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

public class Methoden{
  public String einlesen(){
      String Eingabe = "";
      BufferedReader tastatur = new BufferedReader(new InputStreamReader(System.in));
      try{
      Eingabe = tastatur.readLine();
      }catch(IOException ex){ex.printStackTrace();}
      return Eingabe;
  }
  public int encryptFile(String key,String quelle,String ziel)  throws Exception
  {
    //Einlesen Datei
      BufferedReader sourcefile = new BufferedReader(new FileReader(quelle));
      StringBuffer InputFile = new StringBuffer();
      char ch;
      while (sourcefile.ready())
      {
        ch = (char)sourcefile.read();
        InputFile.append(ch);
      }
      sourcefile.close();
      String SourceInput = InputFile.toString();
    //Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
    Cipher c = Cipher.getInstance( "DES" );
    Key k = new SecretKeySpec( key.getBytes(), "DES" );
    c.init( Cipher.ENCRYPT_MODE, k );
    //Output Stream mit Verschluesselung
    OutputStream targetOutputStream = new FileOutputStream(ziel);
    CipherOutputStream cos = new CipherOutputStream(targetOutputStream, c );
    cos.write( SourceInput.getBytes() );
    cos.close();
    targetOutputStream.close();
    //Rueckagabe der Anzahl der verarbeieteten Zeichen
    return SourceInput.length();
  }
  public int decryptFile(String key,String quelle,String ziel)  throws Exception
  {
      System.out.println("\nDekodiert:");
          //Einlesen Datei
          BufferedInputStream in = new BufferedInputStream(new FileInputStream(quelle));
        //Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
        Cipher c = Cipher.getInstance( "DES" );
        Key k = new SecretKeySpec( key.getBytes(), "DES" );
        c.init( Cipher.DECRYPT_MODE, k );
        CipherInputStream cis = new CipherInputStream(in, c);
        // 
        StringBuffer OutputFile = new StringBuffer();
        int intInput = cis.read();
        while(intInput != -1){
            OutputFile.append((char)intInput);
            intInput = cis.read();
        }
        FileWriter file = new FileWriter(ziel);
        String output = OutputFile.toString();
        file.write(output, 0, output.length());
        file.close();
        in.close();
        //
        return OutputFile.length();
  }
  public String encryptInput(String key,String input)  throws Exception
  {
    //Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
    Cipher c = Cipher.getInstance( "DES" );
    Key k = new SecretKeySpec( key.getBytes(), "DES" );
    c.init( Cipher.ENCRYPT_MODE, k );
    //Output Stream mit crypting
    ByteArrayOutputStream OutputStream = new ByteArrayOutputStream();
    CipherOutputStream cos = new CipherOutputStream(OutputStream,c);
    byte[] inputByte = input.getBytes();
    cos.write(inputByte);
    OutputStream.close();
    return OutputStream.toString();   
    }
  public String decryptInput(String key,String input)  throws Exception
  {
      System.out.println("\nDekodiert:");
          BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(input.getBytes()));
          //Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
        Cipher c = Cipher.getInstance( "DES" );
        Key k = new SecretKeySpec( key.getBytes(), "DES" );
        c.init( Cipher.DECRYPT_MODE, k );
        CipherInputStream cis = new CipherInputStream(in, c);
        StringBuffer decrypted = new StringBuffer();
        int intInput = cis.read();
        while(intInput != -1){
            decrypted.append((char)intInput);
            intInput = cis.read();
        }
        return decrypted.toString();       
  }
}

Das sind die Ergebnisse die ich nach Aufrufen der Methoden und uebergeben der Parameter erhalte. Wie gesagt, da fehlt was wenn man das ganze wieder entschluesselt...

Text Verschluesseln
------------------
Bitte einen Schluessel eingeben (exakt 8 Zeichen)
Schluessel: 12345678
Bitte den zu verschluesselnden Text angeben.
Text: 12345678901234567890123456789012345678901234567890
Vorgang wird bearbeitet
Verschluesselung abgeschlossen
–ЈxÕŒ‰i%§. ¸&÷Åœ<`º¡çæý¼@rDí¶´n›)r“[sȖЈxÕŒ‰

Text Entschluesseln
------------------
Bitte den passenden Schluessel eingeben (exakt 8 Zeichen)
Schluessel: 12345678
Bitte die verschluesselte Text eingeben
Text: –ЈxÕŒ‰i%§. ¸&÷Åœ<`º¡çæý¼@rDí¶´n›)r“[sȖЈxÕŒ‰
Vorgang wird bearbeitet

Dekodiert:
Text enschluesselt
Text: 1234567890123456789012345678901234567890
 
Zu Frage 1: in encryptInput muss der CipherOutputStream geschlossen werden, damit die Daten vollständig übernommen werden
Code:
public String encryptInput(String key,String input)  throws Exception {

    //Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
    Cipher c = Cipher.getInstance( "DES" );
    Key k = new SecretKeySpec( key.getBytes(), "DES" );
    c.init( Cipher.ENCRYPT_MODE, k );

    //Output Stream mit crypting
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    CipherOutputStream cos = new CipherOutputStream( baos, c);
    byte[] inputBytes = input.getBytes();
    cos.write( inputBytes);
    cos.close();
    baos.close();

    return baos.toString();   
}
 
Zu Frage 2: in encrpytFile wird zum Einlesen ein BufferedReader verwendet. Reader und Writer sind aber nur für textuelle Daten brauchbar; Binärdateien werden damit nicht korrekt verarbeitet. Arbeite hier also lieber mit einem FileInputStream.
 
So, hab alles angepasst. Jetzt klappt’s soweit ganz gut mit den Bildern. Hatte da einen ziemlichen Mischmasch an verschiedenen Streams drin. Jetzt sind es alles FileInputStreams.

Leider klappen z.B. zip, rar Dateien nicht und irgendwie alles was ein bisschen größer ist.
Habe ich die Möglichkeit das ganze noch irgendwie zu optimieren?!
Kann ich den Status ausgeben wieviel Prozent schon erledigt sind?
Gibt’s elegantere Lösungen.

Code:
public void encryptFile(String key,String quelle,String ziel)  throws Exception
  {
	//Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
    Cipher c = Cipher.getInstance( "DES" );
    Key k = new SecretKeySpec( key.getBytes(), "DES" );
    c.init( Cipher.ENCRYPT_MODE, k );
    // Zieldatei einbinden, CipherStream mit Informationen fuettern
	OutputStream targetStream = new FileOutputStream(ziel);
    CipherOutputStream cos = new CipherOutputStream(targetStream, c );
    // Verschluesselung der Quelldaten und Ausgabe in Zieldatei
    FileInputStream sourcefile = new FileInputStream(quelle);
    int inbyte = sourcefile.read();
    while(inbyte != -1){
    	cos.write(inbyte);
    	inbyte = sourcefile.read();
    }
    // Schliessen der Streams
    targetStream.close();
    sourcefile.close();
    cos.close();
  }

Code:
public void decryptFile(String key,String quelle,String ziel)  throws Exception
  {
	  	// Key uebergabe an SecretKeySpec und Chiper initialisierung mit key
    	Cipher c = Cipher.getInstance( "DES" );
    	Key k = new SecretKeySpec( key.getBytes(), "DES" );
    	c.init( Cipher.DECRYPT_MODE, k );
    	// Quelldatei einbinden, CipherStream mit Informationen fuettern
	  	FileInputStream sourceStream = new FileInputStream(quelle);
    	CipherInputStream cis = new CipherInputStream(sourceStream, c);
    	// Enschluesselung der Quelldaten und Ausgabe in Zieldatei
    	FileOutputStream targetStream = new FileOutputStream(ziel);
        int outbyte = cis.read();
    	while(outbyte != -1){
    		targetStream.write(outbyte);
    		outbyte = cis.read();
    	}
    	// Schliessen der Streams
    	targetStream.close();
    	sourceStream.close();
    	cis.close();
  }
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben