package jzj.timingtraining.security;import java.io.File;import java.io.IOException;import java.security.GeneralSecurityException;import java.util.UUID;public class ZipCipherUtil {/** * 對目錄srcFile下的所有檔案目錄進行先壓縮後加密,然後儲存為destfile * * @param srcFile * 要操作的檔案或檔案夾 * @param destfile * 壓縮加密後存放的檔案 * @param keyfile * 密鑰 */public void encryptZip(String srcFile, String destfile, String keyStr) {File temp = new File("/sdcard/" +UUID.randomUUID().toString() + ".zip");temp.deleteOnExit();// 先壓縮檔new ZipUtil().zip(srcFile, temp.getAbsolutePath());// 對檔案加密try {new CipherUtil().encrypt(temp.getAbsolutePath(), destfile, keyStr);} catch (GeneralSecurityException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}temp.delete();deleteDir(new File(srcFile));}/** * 對檔案srcfile進行先解密後解壓縮,然後解壓縮到目錄destfile下 * * @param srcfile * 要解密和解壓縮的檔案名稱 * @param destfile * 解壓縮後的目錄 * @param publicKey * 密鑰 */public void decryptUnzip(String srcfile, String destfile, String keyStr) {File temp = new File(UUID.randomUUID().toString() + ".zip");temp.deleteOnExit();// 先對檔案解密try {new CipherUtil().decrypt(srcfile, temp.getAbsolutePath(), keyStr);} catch (GeneralSecurityException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 解壓縮new ZipUtil().unZip(temp.getAbsolutePath(),destfile);temp.delete();deleteDir(new File(srcfile));}public static void main(String[] args) throws Exception {long l1 = System.currentTimeMillis();//加密new ZipCipherUtil().encryptZip("d:\\photo", "d:\\photo.zip", "12345");//解密new ZipCipherUtil().decryptUnzip("d:\\photo.zip", "d:\\photo", "12345");long l2 = System.currentTimeMillis();//System.out.println((l2 - l1) + "毫秒.");//System.out.println(((l2 - l1) / 1000) + "秒.");}/** * 遞迴刪除目錄下的所有檔案及子目錄下所有檔案 * @param dir 將要刪除的檔案目錄 * @return boolean Returns "true" if all deletions were successful. * If a deletion fails, the method stops attempting to * delete and returns "false". */ private static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); //遞迴刪除目錄中的子目錄下 for (int i=0; i<children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // 目錄此時為空白,可以刪除 return dir.delete(); }}
package jzj.timingtraining.security;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;import java.util.zip.ZipOutputStream;/** * 對檔案或檔案夾進行壓縮和解壓 * */public class ZipUtil {/** * 添加到壓縮檔中 * @param out * @param f * @param base * @throws Exception */private void directoryZip(ZipOutputStream out, File f, String base) throws Exception {// 如果傳入的是目錄if (f.isDirectory()) {File[] fl = f.listFiles();// 建立壓縮的子目錄out.putNextEntry(new ZipEntry(base + "/"));if (base.length() == 0) {base = "";} else {base = base + "/";}for (int i = 0; i < fl.length; i++) {directoryZip(out, fl[i], base + fl[i].getName());}} else {// 把壓縮檔加入rar中out.putNextEntry(new ZipEntry(base));FileInputStream in = new FileInputStream(f);byte[] bb = new byte[10240];int aa = 0;while ((aa = in.read(bb)) != -1) {out.write(bb, 0, aa);}in.close();}}/** * 壓縮檔 * * @param zos * @param file * @throws Exception */private void fileZip(ZipOutputStream zos, File file) throws Exception {if (file.isFile()) {zos.putNextEntry(new ZipEntry(file.getName()));FileInputStream fis = new FileInputStream(file);byte[] bb = new byte[10240];int aa = 0;while ((aa = fis.read(bb)) != -1) {zos.write(bb, 0, aa);}fis.close();System.out.println(file.getName());} else {directoryZip(zos, file, "");}}/** * 解壓縮檔案 * * @param zis * @param file * @throws Exception */private void fileUnZip(ZipInputStream zis, File file) throws Exception {ZipEntry zip = zis.getNextEntry();if (zip == null)return;String name = zip.getName();File f = new File(file.getAbsolutePath() + "/" + name);if (zip.isDirectory()) {f.mkdirs();fileUnZip(zis, file);} else {f.createNewFile();FileOutputStream fos = new FileOutputStream(f);byte b[] = new byte[10240];int aa = 0;while ((aa = zis.read(b)) != -1) {fos.write(b, 0, aa);}fos.close();fileUnZip(zis, file);}}/** * 根據filePath建立相應的目錄 * @param filePath * @return * @throws IOException */private File mkdirFiles(String filePath){File file = new File(filePath);if(!file.getParentFile().exists()){file.getParentFile().mkdirs();}try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}return file;}/** * 對zipBeforeFile目錄下的檔案壓縮,儲存為指定的檔案zipAfterFile * * @param zipBeforeFile壓縮之前的檔案 * @param zipAfterFile壓縮之後的檔案 */public void zip(String zipBeforeFile, String zipAfterFile) {try {ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(mkdirFiles(zipAfterFile)));fileZip(zos, new File(zipBeforeFile));zos.close();} catch (Exception e) {e.printStackTrace();}}/** * 解壓縮檔案unZipBeforeFile儲存在unZipAfterFile目錄下 * * @param unZipBeforeFile解壓之前的檔案 * @param unZipAfterFile解壓之後的檔案 */public void unZip(String unZipBeforeFile, String unZipAfterFile) {try {ZipInputStream zis = new ZipInputStream(new FileInputStream(unZipBeforeFile));File f = new File(unZipAfterFile);f.mkdirs();fileUnZip(zis, f);zis.close();} catch (Exception e) {e.printStackTrace();}}}
package jzj.timingtraining.security;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.security.GeneralSecurityException;import java.security.Key;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;/** * 使用AES對檔案進行加密和解密 * */public class CipherUtil {/** * 使用AES對檔案進行加密和解密 * */private static String type = "AES";/** * 把檔案srcFile加密後儲存為destFile * @param srcFile 加密前的檔案 * @param destFile 加密後的檔案 * @param privateKey 密鑰 * @throws GeneralSecurityException * @throws IOException */public void encrypt(String srcFile, String destFile, String privateKey) throws GeneralSecurityException, IOException {Key key = getKey(privateKey);Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key);FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream(srcFile);fos = new FileOutputStream(mkdirFiles(destFile));crypt(fis, fos, cipher);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fis != null) {fis.close();}if (fos != null) {fos.close();}}}/** * 把檔案srcFile解密後儲存為destFile * @param srcFile 解密前的檔案 * @param destFile 解密後的檔案 * @param privateKey 密鑰 * @throws GeneralSecurityException * @throws IOException */public void decrypt(String srcFile, String destFile, String privateKey) throws GeneralSecurityException, IOException {Key key = getKey(privateKey);Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, key);FileInputStream fis = null;FileOutputStream fos = null;try {fis = new FileInputStream(srcFile);fos = new FileOutputStream(mkdirFiles(destFile));crypt(fis, fos, cipher);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fis != null) {fis.close();}if (fos != null) {fos.close();}}}/** * 根據filePath建立相應的目錄 * @param filePath要建立的檔案路經 * @returnfile檔案 * @throws IOException */private File mkdirFiles(String filePath) throws IOException {File file = new File(filePath);if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}file.createNewFile();return file;}/** * 產生指定字串的密鑰 * @param secret 要產生密鑰的字串 * @return secretKey 產生後的密鑰 * @throws GeneralSecurityException */private static Key getKey(String secret) throws GeneralSecurityException {KeyGenerator kgen = KeyGenerator.getInstance(type);kgen.init(128, new SecureRandom(secret.getBytes()));SecretKey secretKey = kgen.generateKey();return secretKey;}/** * 加密解密流 * @param in加密解密前的流 * @param out加密解密後的流 * @param cipher加密解密 * @throws IOException * @throws GeneralSecurityException */private static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException, GeneralSecurityException {int blockSize = cipher.getBlockSize() * 1000;int outputSize = cipher.getOutputSize(blockSize);byte[] inBytes = new byte[blockSize];byte[] outBytes = new byte[outputSize];int inLength = 0;boolean more = true;while (more) {inLength = in.read(inBytes);if (inLength == blockSize) {int outLength = cipher.update(inBytes, 0, blockSize, outBytes);out.write(outBytes, 0, outLength);} else {more = false;}}if (inLength > 0)outBytes = cipher.doFinal(inBytes, 0, inLength);elseoutBytes = cipher.doFinal();out.write(outBytes);}}