首页

通过java.util.zip压缩包文件解析常见处理及安全密钥加解密ZipEncrypt处理

标签:ZipInputStream,ZipOutputStream,ZipEntry,PrivateKey,PublicKey,公钥,私钥,KeyPairGenerator,SecureRandom     发布时间:2017-03-14   

该类通过对常见zip包文件通过java.util.zip包下的ZipInputStream、ZipOutputStream进行文件解/压缩处理,并通过RSA密钥安全协议对包进行加解密打包认证,具体参见代码

import java.io.ByteArrayInputStream;@b@import java.io.ByteArrayOutputStream;@b@import java.io.File;@b@import java.io.FileInputStream;@b@import java.io.FileOutputStream;@b@import java.io.IOException;@b@import java.io.ObjectInputStream;@b@import java.io.ObjectOutputStream;@b@import java.security.Key;@b@import java.security.KeyPair;@b@import java.security.KeyPairGenerator;@b@import java.security.NoSuchAlgorithmException;@b@import java.security.PrivateKey;@b@import java.security.PublicKey;@b@import java.security.SecureRandom;@b@import java.util.UUID;@b@import java.util.zip.Deflater;@b@import java.util.zip.Inflater;@b@import java.util.zip.ZipEntry;@b@import java.util.zip.ZipInputStream;@b@import java.util.zip.ZipOutputStream;@b@import javax.crypto.Cipher;@b@import com.woopa.common.util.FileUtils;@b@@b@public class ZipEncrypt {@b@	private PrivateKey privateKey = null;@b@	private PublicKey publicKey = null;@b@@b@	/**@b@	 * 解压缩文件.@b@	 * @b@	 * @param intputFilePath@b@	 *            要解压缩文件路径及文件名@b@	 * @param outputFilePath@b@	 *            解压缩文件输出路径@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要解压缩的文件不存在)@b@	 */@b@	public String unzipFile(String intputFilePath, String outputFilePath) {@b@		String result = "0";@b@		boolean b = isExists(intputFilePath);@b@		if (!b) {@b@			return "1:要解压缩的文件不存在";@b@		} else {@b@			File file = new File(outputFilePath);@b@			if (!file.exists()) {@b@				file.mkdirs();@b@			}@b@			File outFile = new File(outputFilePath);@b@			if (!outFile.exists()) {@b@				outFile.mkdirs();@b@			}@b@			unZip(outputFilePath, intputFilePath);@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 解压缩文件对象.@b@	 * @b@	 * @param intputFile@b@	 *            要解压缩的文件对象@b@	 * @param outputFilePath@b@	 *            解压缩文件输出路径@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要解压缩的文件格式错误)@b@	 */@b@	public String unzipFile(File intputFile, String outputFilePath) {@b@		String result = "0";@b@		if (intputFile == null) {@b@			return "1:要解压缩的文件不存在";@b@		}@b@		String inFileName = intputFile.getName();@b@		String endName = inFileName.split("\\.")[1];@b@		if (!endName.equals("zip")) {@b@			result = "1:解压缩的文件格式错误";@b@		} else {@b@			File file = new File(outputFilePath);@b@			if (!file.exists()) {@b@				file.mkdirs();@b@			}@b@			String infile = intputFile.getAbsolutePath();@b@			unZip(outputFilePath, infile);@b@			result = "0";@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 压缩文件.@b@	 * @b@	 * @param intputFilePath@b@	 *            要压缩文件路径及文件名@b@	 * @param outputFilePath@b@	 *            压缩文件输出路径(压缩文件的命名为:原文件名+.zip后缀)@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要压缩的文件不存在)@b@	 */@b@	public String zipFile(String intputFilePath, String outputFilePath) {@b@		String result = "0";@b@		boolean b = isExists(intputFilePath);@b@		if (b) {@b@			File file = new File(intputFilePath);@b@			result = zipFile(file, outputFilePath);@b@		} else {@b@			result = "1:要压缩的文件不存在";@b@		}@b@		return result;@b@	}@b@@b@	public String zipFile(String intputFilePath, String outputFilePath,@b@			String name) {@b@		String result = "0";@b@		boolean b = isExists(intputFilePath);@b@		if (b) {@b@			File file = new File(intputFilePath);@b@			result = zipFile(file, outputFilePath, name);@b@		} else {@b@			result = "1:要压缩的文件不存在";@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 压缩文件对象.@b@	 * @b@	 * @param intputFile@b@	 *            要压缩的文件对象@b@	 * @param outputFilePath@b@	 *            压缩文件输出路径(压缩文件的命名为:原文件名+.zip后缀)@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要压缩的文件不存在)@b@	 */@b@	public String zipFile(File intputFile, String outputFilePath) {@b@		String result = "0";@b@		if (intputFile == null) {@b@			result = "1:要压缩的文件不存在";@b@		} else {@b@			File outfile = new File(outputFilePath);@b@			if (!outfile.exists()) {@b@				outfile.mkdirs();@b@			}@b@			String fileName = intputFile.getName();@b@@b@			String tempFile = "/" + FileUtils.getFileNameWithoutType(fileName)@b@					+ ".zip";@b@			outputFilePath += tempFile;@b@			String indirectory = intputFile.getAbsolutePath();@b@			zip(indirectory, outputFilePath);@b@			return result;@b@		}@b@		return result;@b@	}@b@@b@	public String zipFile(File intputFile, String outputFilePath, String name) {@b@		String result = "0";@b@		if (intputFile == null) {@b@			result = "1:要压缩的文件不存在";@b@		} else {@b@			File outfile = new File(outputFilePath);@b@			if (!outfile.exists()) {@b@				outfile.mkdirs();@b@			}@b@@b@			String tempFile = name + ".zip";@b@			outputFilePath += tempFile;@b@			String indirectory = intputFile.getAbsolutePath();@b@			zip(indirectory, outputFilePath);@b@			return result;@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 解密文件.@b@	 * @b@	 * @param intputFilePath@b@	 *            要解密文件路径及文件名@b@	 * @param outputFilePath@b@	 *            解密文件输出路径@b@	 * @param prikeyPath@b@	 *            私钥文件路径@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要解密的文件不存在)@b@	 */@b@	public String decryptFile(String intputFilePath, String outputFilePath,@b@			String prikeyPath) {@b@		String result = "0";@b@		boolean b = isExists(intputFilePath);@b@		if (!b) {@b@			return "1:要解密的文件不存在";@b@		}@b@		File file = new File(outputFilePath);@b@		if (!file.exists()) {@b@			file.mkdirs();@b@		}@b@		File temp = new File(intputFilePath);@b@@b@		outputFilePath += "/" + temp.getName();@b@		try {@b@			decrypt(intputFilePath, outputFilePath, getKey(prikeyPath));@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 解密文件对象.@b@	 * @b@	 * @param intputFile@b@	 *            解密的文件对象@b@	 * @param outputFilePath@b@	 *            解密文件输出路径@b@	 * @param prikeyPath@b@	 *            私钥文件路径@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要解密的文件不存在)@b@	 */@b@	public String decryptFile(File intputFile, String outputFilePath,@b@			String prikeyPath) {@b@		String result = "0";@b@		if (intputFile == null) {@b@			return "1:要解密的文件不存在";@b@		}@b@		File file = new File(outputFilePath);@b@		if (!file.exists()) {@b@			file.mkdirs();@b@		}@b@		String inFile = intputFile.getAbsolutePath();@b@		String inName = intputFile.getName();@b@@b@		outputFilePath += "/" + inName;@b@		try {@b@			decrypt(inFile, outputFilePath, getKey(prikeyPath));@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 加密文件.@b@	 * @b@	 * @param intputFilePath@b@	 *            要加密文件路径及文件名@b@	 * @param outputFilePath@b@	 *            加密文件输出路径(加密文件的命名为:原文件名)@b@	 * @param pubkeyPath@b@	 *            公钥文件路径@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要加密的文件不存在)@b@	 */@b@	public String encryptFile(String intputFilePath, String outputFilePath,@b@			String pubkeyPath) {@b@		String result = "0";@b@		boolean b = isExists(intputFilePath);@b@		if (!b) {@b@			return "1:要加密的文件不存在";@b@		} else {@b@			File file = new File(outputFilePath);@b@			if (!file.exists()) {@b@				file.mkdirs();@b@			}@b@			File tempfile = new File(intputFilePath);@b@@b@			outputFilePath += "/" + tempfile.getName();@b@			try {@b@				encrypt(intputFilePath, outputFilePath, getKey(pubkeyPath));@b@			} catch (Exception e) {@b@				e.printStackTrace();@b@			}@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 加密文件对象.@b@	 * @b@	 * @param intputFile@b@	 *            要加密的文件对象@b@	 * @param outputFilePath@b@	 *            加密文件输出路径(加密文件的命名为:原文件名)@b@	 * @param pubkeyPath@b@	 *            公钥文件路径@b@	 * @return 0:成功 1:失败+失败原因 (例如:1:要加密的文件不存在)@b@	 */@b@	public String encryptFile(File intputFile, String outputFilePath,@b@			String pubkeyPath) {@b@		String result = "0";@b@		if (intputFile == null) {@b@			return "1:要加密的文件不存在";@b@		} else {@b@			File file = new File(outputFilePath);@b@			if (!file.exists()) {@b@				file.mkdirs();@b@			}@b@			String inpath = intputFile.getAbsolutePath();@b@@b@			outputFilePath += "/" + intputFile.getName();@b@@b@			try {@b@				encrypt(inpath, outputFilePath, getKey(pubkeyPath));@b@			} catch (Exception e) {@b@				e.printStackTrace();@b@			}@b@		}@b@		return result;@b@	}@b@@b@	/**@b@	 * 判断文件是否存在@b@	 * @b@	 * @param inputFilePath@b@	 * @return@b@	 */@b@	private boolean isExists(String inputFilePath) {@b@		boolean b = false;@b@		File tempfile = new File(inputFilePath);@b@		if (tempfile.exists()) {@b@			b = true;@b@		}@b@		return b;@b@	}@b@@b@	/**@b@	 * 目录压缩@b@	 * @b@	 * @param out@b@	 * @param f@b@	 * @param base@b@	 * @throws Exception@b@	 */@b@	private void directoryZip(ZipOutputStream out, File f, String base)@b@			throws Exception {@b@		if (f.isDirectory()) {@b@			File[] fl = f.listFiles();@b@			out.putNextEntry(new ZipEntry(base + "/"));@b@			if (base.length() == 0) {@b@				base = "";@b@			} else {@b@				base = base + "/";@b@			}@b@			for (int i = 0; i < fl.length; i++) {@b@				directoryZip(out, fl[i], base + fl[i].getName());@b@			}@b@		} else {@b@			out.putNextEntry(new ZipEntry(base));@b@			FileInputStream in = new FileInputStream(f);@b@			byte[] bb = new byte[2048];@b@			int aa = 0;@b@			while ((aa = in.read(bb)) != -1) {@b@				out.write(bb, 0, aa);@b@			}@b@			in.close();@b@		}@b@	}@b@@b@	/**@b@	 * 压缩文件@b@	 * @b@	 * @param zos@b@	 * @param file@b@	 * @throws Exception@b@	 */@b@	private void fileZip(ZipOutputStream zos, File file) throws Exception {@b@		if (file.isFile()) {@b@			zos.putNextEntry(new ZipEntry(file.getName()));@b@			FileInputStream fis = new FileInputStream(file);@b@			byte[] bb = new byte[2048];@b@			int aa = 0;@b@			while ((aa = fis.read(bb)) != -1) {@b@				zos.write(bb, 0, aa);@b@			}@b@			fis.close();@b@		} else {@b@			directoryZip(zos, file, "");@b@		}@b@	}@b@@b@	/**@b@	 * 对directory目录下的文件压缩,保存为指定的文件zipFile@b@	 * @b@	 * @param directory@b@	 * @param zipFile@b@	 */@b@	private void zip(String directory, String zipFile) {@b@		try {@b@			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(@b@					zipFile));@b@			fileZip(zos, new File(directory));@b@			zos.close();@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@		}@b@	}@b@@b@	/**@b@	 * 压缩byte数组@b@	 * @b@	 * @param fileByte@b@	 * @return@b@	 */@b@	public byte[] zipByte(byte[] fileByte) {@b@		byte[] temp = new byte[fileByte.length];@b@		Deflater compresser = new Deflater();@b@		compresser.setInput(fileByte);@b@		compresser.finish();@b@		int len = compresser.deflate(temp);@b@		return zipBytecut(fileByte, len);@b@	}@b@@b@	private byte[] zipBytecut(byte[] fileByte, int len) {@b@		byte[] temp = new byte[len];@b@		Deflater compresser = new Deflater();@b@		compresser.setInput(fileByte);@b@		compresser.finish();@b@		compresser.deflate(temp);@b@		return temp;@b@	}@b@@b@	/**@b@	 * 解压缩byte数组@b@	 * @b@	 * @param fileByte@b@	 * @return@b@	 * @throws Exception@b@	 */@b@	public byte[] upzipByte(byte[] fileByte, int len) {@b@		try {@b@			Inflater decompresser = new Inflater();@b@			decompresser.setInput(fileByte, 0, fileByte.length);@b@			byte[] result = new byte[len];@b@			decompresser.inflate(result);@b@			decompresser.end();@b@			return result;@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@			return null;@b@		}@b@	}@b@@b@	/**@b@	 * 解压缩文件@b@	 * @b@	 * @param zis@b@	 * @param file@b@	 * @throws Exception@b@	 */@b@	private void fileUnZip(ZipInputStream zis, File file) throws Exception {@b@		ZipEntry zip = zis.getNextEntry();@b@		if (zip == null)@b@			return;@b@		String name = zip.getName();@b@		File f = new File(file.getAbsolutePath() + "/" + name);@b@		if (zip.isDirectory()) {@b@			f.mkdirs();@b@			fileUnZip(zis, file);@b@		} else {@b@			f.createNewFile();@b@			FileOutputStream fos = new FileOutputStream(f);@b@			byte b[] = new byte[2048];@b@			int aa = 0;@b@			while ((aa = zis.read(b)) != -1) {@b@				fos.write(b, 0, aa);@b@			}@b@			fos.close();@b@			fileUnZip(zis, file);@b@		}@b@	}@b@@b@	/**@b@	 * 解压缩文件zipFile保存在directory目录下@b@	 * @b@	 * @param directory@b@	 * @param zipFile@b@	 */@b@	private void unZip(String directory, String zipFile) {@b@		try {@b@			ZipInputStream zis = new ZipInputStream(@b@					new FileInputStream(zipFile));@b@			File f = new File(directory);@b@			f.mkdirs();@b@			fileUnZip(zis, f);@b@			zis.close();@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@		}@b@	}@b@@b@	/**@b@	 * 生成密钥对并保存到文件@b@	 * @b@	 * @param keyfile@b@	 */@b@	public boolean createKey(String priKeyPath, String pubKeyPath) {@b@		boolean b = false;@b@		SecureRandom sr = new SecureRandom();@b@		KeyPairGenerator kg;@b@		try {@b@			kg = KeyPairGenerator.getInstance("RSA");@b@			kg.initialize(512, sr);@b@			KeyPair kp = kg.generateKeyPair();@b@			this.privateKey = kp.getPrivate();@b@			this.publicKey = kp.getPublic();@b@			File f = new File(priKeyPath); // 保存私钥@b@			String dir = priKeyPath.replace(f.getName(), "");@b@			File dirf = new File(dir);@b@			if (!dirf.exists()) {@b@				dirf.mkdirs();@b@			}@b@			f.createNewFile();@b@			FileOutputStream fos = new FileOutputStream(f);@b@			ObjectOutputStream dos = new ObjectOutputStream(fos);@b@			dos.writeObject(this.privateKey);@b@			dos.close();@b@			fos.close();@b@@b@			File f2 = new File(pubKeyPath); // 保存公钥@b@@b@			String dir2 = pubKeyPath.replace(f2.getName(), "");@b@			File dirf2 = new File(dir2);@b@			if (!dirf2.exists()) {@b@				dirf2.mkdirs();@b@			}@b@@b@			f2.createNewFile();@b@			FileOutputStream fos2 = new FileOutputStream(f2);@b@			ObjectOutputStream dos2 = new ObjectOutputStream(fos2);@b@			dos2.writeObject(this.publicKey);@b@			dos2.close();@b@			fos2.close();@b@			b = true;@b@		} catch (NoSuchAlgorithmException e) {@b@			e.printStackTrace();@b@		} catch (IOException e) {@b@			e.printStackTrace();@b@		}@b@		return b;@b@	}@b@@b@	/**@b@	 * 根据key的路径文件获得持久化成文件的key@b@	 * <P>@b@	 * 例子: ZipEncrypt.getKey("E:/keypath/private.key");@b@	 * @b@	 * @param keyPath@b@	 * @return key@b@	 */@b@	private Key getKey(String keyPath) throws Exception {@b@		Key key = null;@b@		FileInputStream fis = new FileInputStream(keyPath);@b@		ObjectInputStream ofs = new ObjectInputStream(fis);@b@		key = (Key) ofs.readObject();@b@		ofs.close();@b@		fis.close();@b@		return key;@b@	}@b@@b@	/**@b@	 * 把文件srcFile加密后存储为destFile@b@	 * @b@	 * @param srcFile@b@	 * @param destFile@b@	 * @param privateKey@b@	 * @throws Exception@b@	 */@b@	private void encrypt(String srcFile, String destFile, Key privateKey)@b@			throws Exception {@b@		Cipher cipher = Cipher.getInstance("RSA");@b@		cipher.init(Cipher.ENCRYPT_MODE, privateKey);@b@		FileInputStream fis = new FileInputStream(srcFile);@b@		FileOutputStream fos = new FileOutputStream(destFile);@b@		byte[] b = new byte[53];@b@		while (fis.read(b) != -1) {@b@			fos.write(cipher.doFinal(b));@b@		}@b@		fos.close();@b@		fis.close();@b@	}@b@@b@	/**@b@	 * 把文件srcFile解密后存储为destFile@b@	 * @b@	 * @param srcFile@b@	 * @param destFile@b@	 * @param privateKey@b@	 * @throws Exception@b@	 */@b@	private void decrypt(String srcFile, String destFile, Key privateKey)@b@			throws Exception {@b@		Cipher cipher = Cipher.getInstance("RSA");@b@		cipher.init(Cipher.DECRYPT_MODE, privateKey);@b@		FileInputStream fis = new FileInputStream(srcFile);@b@		FileOutputStream fos = new FileOutputStream(destFile);@b@		byte[] b = new byte[64];@b@		while (fis.read(b) != -1) {@b@			fos.write(cipher.doFinal(b));@b@		}@b@		fos.close();@b@		fis.close();@b@	}@b@@b@	/**@b@	 * 对byte数组进行加密@b@	 * @b@	 * @param input@b@	 * @param keyPath@b@	 * @return@b@	 * @throws Exception@b@	 */@b@	public byte[] encryptByte(byte[] input, String pubKeyPath) {@b@		try {@b@			byte[] result = null;@b@			Cipher cipher = Cipher.getInstance("RSA");@b@			cipher.init(Cipher.ENCRYPT_MODE, (PublicKey) getKey(pubKeyPath));@b@			ByteArrayInputStream in = new ByteArrayInputStream(input);@b@			ByteArrayOutputStream baos = new ByteArrayOutputStream();@b@			byte[] b = new byte[53];@b@			while (in.read(b) != -1) {@b@				baos.write(cipher.doFinal(b));@b@			}@b@			result = baos.toByteArray();@b@			baos.close();@b@			in.close();@b@			return result;@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@			return null;@b@		}@b@	}@b@@b@	/**@b@	 * 对byte数组进行解密@b@	 * @b@	 * @param input@b@	 * @param pubKeyPath@b@	 * @return@b@	 * @throws Exception@b@	 */@b@	public byte[] decryptByte(byte[] input, String priKeyPath) {@b@		try {@b@			byte[] result = null;@b@			Cipher cipher = Cipher.getInstance("RSA");@b@			cipher.init(Cipher.DECRYPT_MODE, (PrivateKey) getKey(priKeyPath));@b@			ByteArrayInputStream in = new ByteArrayInputStream(input);@b@			ByteArrayOutputStream baos = new ByteArrayOutputStream();@b@			byte[] b = new byte[64];@b@			while (in.read(b) != -1) {@b@				baos.write(cipher.doFinal(b));@b@			}@b@			result = baos.toByteArray();@b@			baos.close();@b@			in.close();@b@			return result;@b@		} catch (Exception e) {@b@			e.printStackTrace();@b@			return null;@b@		}@b@	}@b@@b@	/**@b@	 * 对目录srcFile下的所有文件目录进行先压缩后加密,然后保存为destfile@b@	 * @b@	 * @param srcFile@b@	 *            要操作的目录,如: "E:/srcFile"@b@	 * @param destfile@b@	 *            压缩加密后存放的文件名,如: "E:/destfile.zip"@b@	 * @param keyfile@b@	 *            公钥存放地点@b@	 */@b@	public void encryptZip(String srcFile, String destfile, String keyfile)@b@			throws Exception {@b@		File temp = new File(UUID.randomUUID().toString() + ".zip");@b@		temp.deleteOnExit();@b@		zip(srcFile, temp.getAbsolutePath());// 先压缩文件@b@		encrypt(temp.getAbsolutePath(), destfile, publicKey);// 对文件加密@b@		temp.delete();@b@	}@b@@b@	/**@b@	 * 对文件srcfile进行先解密,然后解压缩到目录destfile下@b@	 * @b@	 * @param srcfile@b@	 *            要解密和解压缩的文件名,如: "E:/srcfile.zip"@b@	 * @param destfile@b@	 *            解压缩后的目录,如: "E:/destfile"@b@	 * @param publicKey@b@	 *            公钥@b@	 */@b@	public void decryptUnzip(String srcfile, String destfile, Key publicKey)@b@			throws Exception {@b@		File temp = new File(UUID.randomUUID().toString() + ".zip");@b@		temp.deleteOnExit();@b@		decrypt(srcfile, temp.getAbsolutePath(), publicKey); // 先对文件解密@b@		unZip(destfile, temp.getAbsolutePath());// 解压缩@b@		temp.delete();@b@	}@b@}