Error reading ZIP file

Hi, I got this code:


            ZipEntry ze;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            dec.decrypt(new FileInputStream(gui), baos);
            byte[] buf = baos.toByteArray();
            ByteArrayInputStream bis = new ByteArrayInputStream(buf);
            zis = new ZipInputStream(bis);
          while ((ze = zis.getNextEntry()) != null) {
            System.out.println("Unzipping " + ze.getName());
            ByteArrayOutputStream fout = new ByteArrayOutputStream();
            for (int c = zis.read(); c != -1; c = zis.read()) {
              fout.write(c);
            }
//            ByteArrayInputStream bis = new ByteArrayInputStream(fout.toByteArray());
//            byte bt;
//            while ((bt = (byte)bis.read()) != -1) {
//                System.out.println(bt);
//            }
            zis.closeEntry();
            fout.close();
          }
          zis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

When I try to wrap bis into a ZipInputStream, calling getNextEntry() always returns null. How do I fix this?

Thanks.

Your code seems to be correct. I believe there is an error with your decrypting method and is corrupting the zip file to be read. This slightly modified source code works perfectly…


		try
		{
	        ZipEntry ze;
	        ZipInputStream zis;
	        ByteArrayOutputStream baos = new ByteArrayOutputStream();
	        FileInputStream fis = new FileInputStream("test.zip");
	        
	        for (int c = fis.read(); c != -1; c = fis.read()) {
	        	baos.write(c);
	          }
	        baos.close();
	        
	        byte[] buf = baos.toByteArray();
	        ByteArrayInputStream bis = new ByteArrayInputStream(buf);
	        zis = new ZipInputStream(bis);
	      while ((ze = zis.getNextEntry()) != null) {
	        System.out.println("Unzipping " + ze.getName());
	        ByteArrayOutputStream fout = new ByteArrayOutputStream();

	        zis.closeEntry();
	        fout.close();
	      }
	      zis.close();
	    } catch (IOException e) {
	        e.printStackTrace();
	    } catch (Exception ex) {
	        ex.printStackTrace();
	    }

of course you will need a zip file named “test.zip” in your working directory.

Thanks for your reply. I have my decryption method like this:


package renoria.security;

import java.io.InputStream;
import java.io.OutputStream;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 *
 * @author David
 */
public class Decrypter {
    private Cipher ecipher;
    private Cipher dcipher;
    private static final byte[] iv = new byte[] { (byte) 0xCE, 0x4F, 0x77, (byte) 0xA4, 0x45, (byte) 0xD0,
            0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, 0x20, (byte) 0xFC, 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1,
            0x5C, 0x22, (byte) 0xF7, 0x0C, 0x44, 0x1B, (byte) 0x81, (byte) 0xBD, 0x63, (byte) 0x8D, (byte) 0xD4,
            (byte) 0xC3, (byte) 0xF2, 0x10, 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, 0x6E, 0x66, (byte) 0xEA,
            (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, 0x06, 0x18, 0x4E, (byte) 0xEB, 0x78, (byte) 0x95, (byte) 0xDB,
            (byte) 0xBA, (byte) 0xB6, 0x42, 0x7A, 0x2A, (byte) 0x83, 0x0B, 0x54, 0x67, 0x6D, (byte) 0xE8, 0x65,
            (byte) 0xE7, 0x2F, 0x07, (byte) 0xF3, (byte) 0xA4, 0x27, 0x7B, (byte) 0x85, (byte) 0xB0, 0x26, (byte) 0xFD,
            (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7, (byte) 0xCB, (byte) 0xCC,
            (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, 0x60, 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2,
            (byte) 0x9B, 0x39, 0x5F, (byte) 0x72, 0x11, 0x4C, 0x69, (byte) 0xF8, 0x31, (byte) 0x87, (byte) 0xEE,
            (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, 0x6A, (byte) 0xBC, (byte) 0xB5, 0x6B, 0x59, 0x13, (byte) 0xF1, 0x04,
            0x00, (byte) 0xF6, 0x5A, 0x35, 0x79, 0x48, (byte) 0x8F, 0x15, (byte) 0xCD, (byte) 0x97, 0x57, 0x12, 0x3E, 0x37,
            (byte) 0xFF, (byte) 0x9D, 0x4F, 0x51, (byte) 0xF1, (byte) 0xA3, 0x70, (byte) 0xBB, 0x14, 0x75, (byte) 0xC2,
            (byte) 0xB8, 0x72, (byte) 0xC0, (byte) 0xED, 0x7D, 0x68, (byte) 0xC9, 0x2E, 0x0D, 0x62, 0x46, 0x17, 0x11, 0x4D,
            0x6C, (byte) 0xC4, 0x7E, 0x52, (byte) 0xC1, 0x54, (byte) 0xC7, (byte) 0x9A, 0x1C, (byte) 0x88, 0x58, 0x2C,
            (byte) 0x89, (byte) 0xDC, 0x02, 0x64, 0x40, 0x01, 0x5D, 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, 0x55,
            (byte) 0xD5, (byte) 0xEF, 0x2A, 0x7C, (byte) 0xA7, 0x5B, (byte) 0xA6, 0x6F, (byte) 0x86, (byte) 0x9F, 0x73,
            (byte) 0xE6, 0x0A, (byte) 0xDE, 0x2B, (byte) 0x99, 0x4A, 0x47, (byte) 0x9C, (byte) 0xDF, 0x09, 0x76,
            (byte) 0x9E, 0x30, 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, 0x3B, 0x34, 0x1D, 0x28, 0x0F,
            0x36, (byte) 0xE3, 0x23, (byte) 0xB4, 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, 0x3C, (byte) 0xFE, 0x5E,
            0x32, 0x24, 0x50, 0x1F, 0x3A, 0x43, (byte) 0x8A, (byte) 0x96, 0x41, 0x74, (byte) 0xAC, 0x52, 0x33, (byte) 0xF0,
            (byte) 0xD9, 0x29, (byte) 0x50, (byte) 0xB1, 0x16, (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9,
            (byte) 0x84, 0x7F, 0x61, 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, 0x56, 0x3D, (byte) 0xCA, (byte) 0xF4,
            0x05, (byte) 0xC6, (byte) 0xD5, 0x08, 0x49, 0x4F, 0x64, 0x69, 0x6E, 0x4D, 0x53, 0x7E, 0x46, 0x72, 0x7A 
    };
    
    // 8-byte Salt
    byte[] salt = {
        (byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
        (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
    };

    // Iteration count
    int iterationCount = 1000;
    
    public Decrypter(String passPhrase) {
        try {
            // Create the key
            KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
            SecretKey key = SecretKeyFactory.getInstance(
                "PBEWithMD5AndDES").generateSecret(keySpec);
            ecipher = Cipher.getInstance(key.getAlgorithm());
            dcipher = Cipher.getInstance(key.getAlgorithm());

            // Prepare the parameter to the ciphers
            AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

            // Create the ciphers
            ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        } catch (java.security.InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (java.security.spec.InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (java.security.NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (java.security.InvalidKeyException e) {
            e.printStackTrace();
        }
    }

    // Buffer used to transport the bytes from one stream to another
    byte[] buf = new byte[1024];

    public void encrypt(InputStream in, OutputStream out) {
        try {
            // Bytes written to out will be encrypted
            out = new CipherOutputStream(out, ecipher);

            // Read in the cleartext bytes and write to out to encrypt
            int numRead = 0;
            while ((numRead = in.read(buf)) >= 0) {
                out.write(buf, 0, numRead);
            }
            out.close();
        } catch (java.io.IOException e) {
        }
    }

    public void decrypt(InputStream in, OutputStream out) {
        try {
            // Bytes read from in will be decrypted
            in = new CipherInputStream(in, dcipher);

            // Read in the decrypted bytes and write the cleartext to out
            int numRead = 0;
            while ((numRead = in.read(buf)) >= 0) {
                out.write(buf, 0, numRead);
            }
            out.close();
        } catch (java.io.IOException e) {
        }
    }
}

I use a String as a password. Maybe it is because I don’t flush the stream properly? Or is it because I’m closing it after I write it out?

I am not familiar with java’s encryption classes. I suggest you read tutorials and perform simple tests to isolate your problem.

Okay. Thanks for your help.