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; } }