Simple zip compressor to instead WinRAR.

I am gonna write blogs via English as current as I do. The first article is regarding to pack and encrypt files to instead WinRAR as a simple solution. 

The principle is just utilizing AES algorithm to pack designated folder into one file, or release the designated file to folder. Here is the code without notes, later I will add up them If possible. Hope you can understand.

Note: file name maybe too short to safe, because lesser content will cause higher chance to be deciphered.

 

package com.encrypt;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class EasyEncrypter {

    public static void main(String[] args) {
        args = new String[]{"false", "hh", "ffewf"};
        boolean compress = Boolean.parseBoolean(args[0]);
        String fileName = args[1];
        byte[] key = args[2].getBytes();
        byte[] initialVector = args.length<4||args[3]==null?null:args[3].getBytes();
        System.out.println(compress?"EnCRYPT":"DeCRYPT");
        System.out.println("DIR:"+fileName);
        System.out.println("CODE:"+args[2]);
        System.out.println("OFFSET:"+(args.length<4||args[3]==null?"":args[3]));
        try {
//            if (compress) {
                new EasyEncrypter().ziper(new File(fileName), key, initialVector);
                System.out.println("End:"+fileName+".zip");
//            }else {
                new EasyEncrypter().unZiper(new File(fileName+".zip"), key, initialVector);
                System.out.println("End:"+fileName);
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private static final String PRE_TEXT = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

    public void unZiper(File file, byte[] key, byte[] initialVector) throws Exception {
        byte[] keys = MessageDigest.getInstance("SHA-256").digest(key);
        key = MessageDigest.getInstance("MD5").digest(keys);
        
        FileInputStream fis = new FileInputStream(file);
        byte[] bytes = new byte[8*1024],files;
        String fileDescription = null;
        int len=0,size=0,length=0;
        while(true){
            try {
                if (len==bytes.length) {
                    bytes=Arrays.copyOf(bytes, bytes.length*2);
                }
                length = fis.read(bytes, len, 8);len+=8;
                size+=length==-1?0:length;
                files=Arrays.copyOf(bytes, size);

                files = doAESEncrpyt(false, 256, key, initialVector, files);
                files = decompress(files);
                
                fileDescription = new String(files, "UTF-8").trim();
                if (fileDescription.toUpperCase().endsWith(PRE_TEXT)) {
                    break;
                }
            }catch(Exception e) {
//                    e.printStackTrace();
            }finally {
                if (length<1){
                    break;
                }
            }
        }
        
        String[] array = fileDescription.split(",");
        for(int k=0; k) {
            if (PRE_TEXT.endsWith(array[k])) {break;}
            File tmpfile = new File(new File("").getAbsoluteFile()+File.separator+array[k]);
            tmpfile.getParentFile().mkdirs();
            tmpfile.createNewFile();
            FileOutputStream fos = new FileOutputStream(tmpfile);
            bytes = new byte[Integer.parseInt(array[k+=1])];
            k++;len=0;
            if (bytes.length==0) {continue;}
            while(true){
                length = fis.read(bytes, 0, bytes.length-len);
                if (length<1){
                    break;
                }
                len+=length;
            }

            bytes = doAESEncrpyt(false, 256, key, initialVector, bytes);
            fos.write(decompress(bytes));
            fos.close();
        }
        fis.close();
    }

    public void ziper(File root, byte[] key, byte[] initialVector) throws Exception {
        byte[] keys = MessageDigest.getInstance("SHA-256").digest(key);
        key = MessageDigest.getInstance("MD5").digest(keys);
        
        File zipData = new File(root.getName()+".zipa");
        FileOutputStream dataFos = new FileOutputStream(zipData);
        byte[] buffer = new byte[1024000];
        String fileDescription = "";
        
        for (File subFile : root.listFiles()) {
            if (subFile.isDirectory()) {continue;}
            if (subFile.length()==0) {
                fileDescription+=subFile.getPath()+","+0+","+0+",";
                continue;
            }
            FileInputStream fis = new FileInputStream(subFile);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            int len=0;
            while ((len = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            fis.close();
            
            byte[] bytes = bos.toByteArray();
            bos.close();

            bytes=compress(bytes);
            len = bytes.length;
            bytes = doAESEncrpyt(true, 256, key, initialVector, bytes);
            dataFos.write(bytes);
            fileDescription+=subFile.getPath()+","+bytes.length+","+len+",";
        }
        dataFos.close();

        FileOutputStream fos = new FileOutputStream(root.getName()+".zip");
        byte[] bytes = (fileDescription+PRE_TEXT).getBytes("UTF-8");
        bytes=compress(bytes);
        bytes = doAESEncrpyt(true, 256, key, initialVector, bytes);
        fos.write(bytes);
        
        FileInputStream fis = new FileInputStream(zipData);
        bytes = new byte[10240000];
        while(true){
            int length = fis.read(bytes);
            if (length<1){
                break;
            }
            fos.write(bytes, 0, length);
        }
        fis.close();
        fos.close();
        zipData.delete();
    }
    
    public static byte[] doAESEncrpyt(boolean encrypt, int length, byte[] key, byte[] initialVector, byte[] text) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 
        secureRandom.setSeed(key);
        kgen.init(length, secureRandom);
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        if (initialVector==null||initialVector.length==0){
            initialVector = new byte[16];
        }else {
            initialVector = Arrays.copyOf(initialVector, 16);
        }
        IvParameterSpec iv = new IvParameterSpec(initialVector);
        cipher.init(encrypt?Cipher.ENCRYPT_MODE:Cipher.DECRYPT_MODE, secretKeySpec, iv);
        return cipher.doFinal(text);
    }

    public static byte[] doDESEncrypt(boolean encrypt, int length, byte[] rawKeyData, byte[] initialVector, byte[] encryptText) throws Exception {

        int len = encryptText.length;
        if (encryptText.length % 8 != 0) {
            len = encryptText.length - encryptText.length % 8 + 8;
        }
        byte[] needData = null;
        if (len != 0)
            needData = new byte[len];

        for (int i = 0; i < len; i++) {
            needData[i] = 0x00;
        }

        System.arraycopy(encryptText, 0, needData, 0, encryptText.length);

        byte[] k = new byte[24];
        if (rawKeyData.length == 16) {
            System.arraycopy(rawKeyData, 0, k, 0, rawKeyData.length);
            System.arraycopy(rawKeyData, 0, k, 16, 8);
        } else {
            System.arraycopy(rawKeyData, 0, k, 0, 24);
        }
        KeySpec ks = new DESedeKeySpec(k);
        SecretKeyFactory kf = SecretKeyFactory.getInstance("DESede");
        SecretKey ky = kf.generateSecret(ks);

        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");

        if (initialVector==null||initialVector.length==0){
            initialVector = new byte[8];
        }else {
            initialVector = Arrays.copyOf(initialVector, 8);
        }
        IvParameterSpec iv = new IvParameterSpec(initialVector);
        cipher.init(encrypt?Cipher.ENCRYPT_MODE:Cipher.DECRYPT_MODE, ky, iv);
        return cipher.doFinal(needData);
    }
    

    public static byte[] compress(byte[] data) {
        return compress(data, 0, data.length);
    }
    
    public static byte[] decompress(byte[] data) throws DataFormatException {
        return decompress(data, 0, data.length);
    }
    
    public static byte[] compress(byte[] data, int offset, int len) {
        byte[] output = new byte[0];

        Deflater compresser = new Deflater(Deflater.BEST_COMPRESSION);
        compresser.setInput(data, offset, len);
        compresser.finish();
        ByteArrayOutputStream bos = new ByteArrayOutputStream(len);
        byte[] buf = new byte[1024];
        while (!compresser.finished()) {
            int i = compresser.deflate(buf);
            bos.write(buf, 0, i);
        }
        output = bos.toByteArray();
        try {
            bos.close();
        } catch (IOException e) {
//                e.printStackTrace();
        }
        compresser.end();
        return output;
    }

    public static byte[] decompress(byte[] data, int offset, int len) throws DataFormatException {
        byte[] output = new byte[0];

        Inflater decompresser = new Inflater();
        decompresser.setInput(data, offset, len);

        ByteArrayOutputStream baos = new ByteArrayOutputStream(len);
        byte[] buff = new byte[1024];
        while (!decompresser.finished()) {
            int count = decompresser.inflate(buff);
            baos.write(buff, 0, count);
        }
        output = baos.toByteArray();
        try {
            baos.close();
        } catch (IOException e) {
//                e.printStackTrace();
        }

        decompresser.end();
        return output;
    }

}

 

你可能感兴趣的:(Simple zip compressor to instead WinRAR.)