sswastioyono18
sswastioyono18

Reputation: 11

Failed to Decrypt after compressing string into a text file (AES)

First time posting this so don't go too hard on me (although I've been read this forum quite for some time)

The problem that I encounter using AES in Java is like this.

First, I need to encrypt a string and write it into a text file then compress it, no problem with this. I'm using AES encryption and I define my own key e.g "123"

Second, I need to decompress the file (or extract it?) and decrypt it using the same key that I used on 1st step.

What happen in here is : First step is good but the 2nd one failed on decrypting the file even though the string result is the same, total character, word, etc

Here is the code to write the file

private static void inputKeFile(String input) throws IOException
{
    FileWriter fstream = new FileWriter("C:/Users/Sactio/Desktop/tyo/txtToZip.txt",false);
    BufferedWriter out = new BufferedWriter(fstream);
    out.write(input);
    //Close the output stream
    out.close();
}

to zip the file

private static void doZip() {
        try {

            String filename ="C:/Users/Sactio/Desktop/tyo/txtToZip.txt";
            String zipfilename="C:/Users/Sactio/Desktop/OutputZipWrite";
            File file = new File(filename);
            FileInputStream fis = new FileInputStream(file);
            long length = file.length();
            byte[] buf = new byte[(int)length];
            fis.read(buf,0,buf.length);

            CRC32 crc = new CRC32();
            ZipOutputStream s = new ZipOutputStream(new FileOutputStream(zipfilename));

            s.setLevel(9);

            ZipEntry entry = new ZipEntry(filename);
            entry.setSize((long)buf.length);
            crc.reset();
            crc.update(buf);
            entry.setCrc( crc.getValue());
            s.putNextEntry(entry);
            s.write(buf, 0, buf.length);
            s.finish();
            s.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

and this is the encryption

import javax.crypto.Cipher;  
import javax.crypto.SecretKey;  
import javax.crypto.spec.SecretKeySpec;  

public class JcaTest {  
private Cipher ecipher;  
private Cipher dcipher;  

JcaTest(SecretKey key) {  
    try {  
        ecipher = Cipher.getInstance("AES");  
        dcipher = Cipher.getInstance("AES");  
        ecipher.init(Cipher.ENCRYPT_MODE, key);  
        dcipher.init(Cipher.DECRYPT_MODE, key);  
    } catch (Exception e) {  
        System.out.println("Failed in initialization");  
    }  
}  

public String encrypt(String str) {  
    try {  
        byte[] utf8 = str.getBytes("UTF-8");  
        byte[] enc = ecipher.doFinal(utf8);  

        return new sun.misc.BASE64Encoder().encode(enc);  
    } catch (Exception e) {  
        System.out.println("Failed in Encryption");  
    }  
    return null;  
}  

public String decrypt(String str) {  
    try {  
        byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);  

        byte[] utf8 = dcipher.doFinal(dec);  

        return new String(utf8, "UTF-8");  
    } catch (Exception e) {  
        System.out.println("Failed in Decryption");  
    }  
    return null;  
}  

and last, the extractor for zip

private static void bacaZip(String zipfilename) throws IOException
{

    ZipInputStream zinstream = new ZipInputStream(
     new FileInputStream(zipfilename));


    File file = new File(zipfilename);
    FileInputStream fis = new FileInputStream(file);
    long length = file.length();
    byte[] buf = new byte[(int)length];

    ZipEntry zentry = zinstream.getNextEntry();
    System.out.println("Name of current Zip Entry : " + zentry + "\n");
    while (zentry != null) {
      String entryName = zentry.getName();
      System.out.println("Name of  Zip Entry : " + entryName);
      FileOutputStream outstream = new FileOutputStream("C:/Users/Sactio/Desktop/OutputZipWrite.txt");
      int n;

      while ((n = zinstream.read(buf, 0, buf.length)) > -1) {
        outstream.write(buf, 0, n);

      }
      System.out.println("Successfully Extracted File Name : "
          + entryName);
      outstream.close();

      zinstream.closeEntry();
      zentry = zinstream.getNextEntry();

    }
}

private static void extractZip(String jsonString) throws FileNotFoundException
{

    try {
        bacaZip(jsonString);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        System.err.println("Exception: "+e1);
    }
    StringBuffer contents = new StringBuffer();
    BufferedReader reader = null;

    try {
        reader = new BufferedReader(new FileReader("C:/Users/Sactio/Desktop/OutputZipWrite.txt"));
        String text = null;

        // repeat until all lines is read
        while ((text = reader.readLine()) != null) {
            contents.append(text)
                    .append(System.getProperty(
                            "line.separator"));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // show file contents here
    System.out.println("HASIL: "+contents.toString());
}

If I skip compression and file steps, AES works good, but if I send the string into a file and compress it, AES encryption fail for some reason. Does anyone have any idea for this problem?

Upvotes: 0

Views: 1178

Answers (1)

rossum
rossum

Reputation: 15693

The file you decrypt must be byte-for-byte the same as the output from the encryption process. You say "even though the string result is the same, total character, word, etc" To me that indicates you are treating the encrypted file as text, 'character'. It isn't text, it is bytes. Treating it as text is a recipe for disaster because of the many different ways characters can be expressed as bytes. You need to check byte-for-byte identity and always treat the cyphertext as bytes, not characters.

As @Thilo pointed out, compressing encrypted data is useless. Use the sequence compress -> encrypt -> decrypt -> expand.

Upvotes: 1

Related Questions