Click here to Skip to main content
15,891,184 members
Articles / Programming Languages / Java

Encrypted Zipping of Files in C# and Java

Rate me:
Please Sign up or sign in to vote.
4.47/5 (9 votes)
14 Sep 2008CPOL3 min read 75.2K   5.3K   55  
Source code to create a compressed, encrypted password protected zip file in C# and Java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ZipFramework;

import java.awt.geom.Path2D;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.*;

/**
 *
 * @author Neill Harper
 */
public class FileData extends ZIPObject {

    private File tempFile;
    private FileEntry parent;
    private CRC32 crc32;
    private int[] crcNums = {
        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
        0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
        0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
        0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
        0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
        0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
        0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
        0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
        0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
        0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
        0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
        0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
        0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
        0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
        0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
        0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
        0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
        0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
        0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
        0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
        0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
        0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
        0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
        0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
        0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
        0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
        0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
        0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
        0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
        0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
        0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
        0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
        0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
        0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
        0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
        0x2d02ef8d
    };

    public FileData(FileEntry Parent) throws IOException {
        parent = Parent;
        tempFile = File.createTempFile("zip", null);
        this.fillTempFile();

    }

    @Override
    protected byte[] GetOutput() {
        FileInputStream output = null;
        byte[] outBytes = new byte[(int) tempFile.length()];
        try {
            output = new FileInputStream(tempFile);

            
                output.read(outBytes, 0, outBytes.length);
            
                
            

            return outBytes;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(FileData.class.getName()).log(Level.SEVERE, null, ex);
        } 
        catch(IOException ioE)
        {
            Logger.getLogger(FileData.class.getName()).log(Level.SEVERE, null, ioE);
        }
        finally {
            try {
                output.close();
            } catch (IOException ex) {
                Logger.getLogger(FileData.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return outBytes;
    }

    private void fillTempFile() throws FileNotFoundException, IOException {
        switch (parent.getLfh().getMethod().getMethodValue()) {
            case Method.Stored:
                storedCompression();
                break;
            case Method.Deflated:
                deflateCompression();
                break;
            default:
                throw new UnsupportedOperationException("Not supported yet.");
               

                
                }
        
        if (this.parent.getPassword() != null) {
                    EncryptFileData();


                
        }
        this.parent.getLfh().setCompressedSize((int) tempFile.length());

    }
    
    private void EncryptFileData() throws UnsupportedEncodingException, IOException
        {
            String password = this.parent.getPassword();
            int[] keys = new int[3];
            Random ran = new Random();
            keys[0] = 305419896;
            keys[1] = 591751049;
            keys[2] = 878082192;

            
            byte[] passwordBytes = password.getBytes("US-ASCII");

            for (byte b : passwordBytes)
            {
                updateKeys(keys, b);
            }

            byte[] sbytes = new byte[12];

            byte[] encBuf = new byte[12];

            //encBuf = ConvertsByteArrayToByteArray(sbytes, sbytes.Length);

            ran.nextBytes(encBuf);
            
                     
            
            encBuf[11] = (byte)(this.parent.getLfh().getLastModDataTime().getDosTime() >>8);

            for (int i = 0; i < encBuf.length;i++ )
            {
                encBuf[i] = EncodeByte(keys,encBuf[i]);
            }

            File newTemp = File.createTempFile("zip", null);
            FileOutputStream newTempStream = new FileOutputStream(newTemp);
            BufferedOutputStream bos = new BufferedOutputStream(newTempStream, 2048);

            //Write the encryption header to the new temp file
            newTempStream.write(encBuf, 0, encBuf.length);

            FileInputStream input = null;
            FileChannel fc;  

            try
            {
                input = new FileInputStream(tempFile);
                fc = input.getChannel();
                MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY,0,fc.size());
                
                
                int i;
                byte b;
                long bytecount = 0;
               
                while (bb.hasRemaining())
                {
                   
                    bos.write(EncodeByte(keys, bb.get()));
                    bytecount ++;
                }
            }
            finally
            {
                input.close();
                bos.close();
            }

            tempFile.delete();

            tempFile = newTemp;

        }
    
    private byte EncodeByte(int[] keys, byte b)
        {
            byte t = DecryptByte(keys);
            updateKeys(keys, b);
            return (byte)(t ^ b);
        }
    
    private byte DecryptByte(int[] keys)
        {
            short temp = (short)(keys[2] | 2);
            return (byte)((temp * (temp ^ 1)) >> 8);
        }
    
    
    
    private int crc32Method(int CRC, byte b)
        {
        int i = b & 0xFF;     
        
        long l = (long)CRC & 0xFFFFFFFFL;
        
        
        long crcnum, crcin;
        
        int tempcrc = crcNums[(i ^ (int)(l)) & 0xff];
        
        long holdRes = tempcrc ^ (l >> 8);
        
        
        
               
        int ret = (int)(holdRes & 0xFFFFFFFFL);
        
        
            return ret;
        }
    
    

    private void updateKeys(int[] keys, byte b)
        {
            keys[0] = crc32Method(keys[0], b);
            keys[1] += keys[0] & 0xFF;
            
            keys[1] = ((keys[1] * 134775813 + 1));
            
            keys[2] = crc32Method(keys[2], (byte)(keys[1] >> 24));
    }
    
    private void storedCompression() throws FileNotFoundException, IOException
        {

            FileInputStream input = null;
            FileOutputStream output = null;
            try
            {
                crc32 = new CRC32();
                input = new FileInputStream(this.parent.getFilePath());
                
                output = new FileOutputStream(tempFile);
                

                byte[] inBytes = new byte[1024];
                int offset = 0;
                int numberRead = 0;
                while ((numberRead = input.read(inBytes, 0, 1024)) != -1)
                {
                    crc32.update(inBytes, 0,numberRead);
                    
                    output.write(inBytes, 0, numberRead);

                    offset += numberRead;
                }

                long c32 = crc32.getValue();
                this.parent.getLfh().setCRC32((int)crc32.getValue());

            }
            finally
            {

                input.close();
                output.close();
            }
        }
    
    private void deflateCompression() throws FileNotFoundException, IOException
        {
            FileInputStream input = null;
            FileOutputStream output = null;
            DeflaterOutputStream dos = null;
            
             
                   
            try
            {
                crc32 = new CRC32();
                input = new FileInputStream(this.parent.getFilePath());
                               
                output = new FileOutputStream(tempFile);
                Deflater d = new Deflater(Deflater.BEST_COMPRESSION,true);
                dos = new DeflaterOutputStream(output,d);
                

                byte[] inBytes = new byte[1024];
                int offset = 0;
                int numberRead = 0;
                while ((numberRead = input.read(inBytes, 0, 1024)) != -1)
                {
                    crc32.update(inBytes, 0,numberRead);
                    
                    dos.write(inBytes, 0, numberRead);

                    offset += numberRead;
                }

                long c32 = crc32.getValue();
                this.parent.getLfh().setCRC32((int)crc32.getValue());

            }
            finally
            {

                input.close();
                dos.close();
            }

            

        }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
United Kingdom United Kingdom
I am an iSeries Synon/RPG programmer, who likes to program in C# and Java in my spare time.

Comments and Discussions