附件加密存储
使用 javax.crypto.CipherInputStream javax.crypto.CipherOutputStream 对文件加解密。
对文件流的操作主要使用 hutool 工具包,引入依赖
<!-- hutool 工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
直接贴代码:
public class FileEncryption {
//密钥
public final static String sKey = "AD67EA2F3BE6E5ADD368DFE03120BXZ8PCCfPDL40GJFQ4GL";
private static FileEncryption fileEncryption = new FileEncryption();
private FileEncryption(){}
public static FileEncryption getInstance(){
return fileEncryption;
}
/**
* 文件加密
*
* @param sourcePath 原始文件路径
* @param targetPath 加密后的存储路径
*/
public void encryptFile(String sourcePath, String targetPath) {
try {
CipherInputStream cipherInputStream = getCipherInputStream(new FileInputStream(sourcePath));
FileUtil.writeFromStream(cipherInputStream, targetPath);
IoUtil.close(cipherInputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
/**
* 解密文件
* @param sourcePath 待解密的文件路径
* @param targetPath 解密后的文件路径
*/
public void decryptFile(String sourcePath, String targetPath) {
try {
byte[] bytes = IoUtil.readBytes(new FileInputStream(sourcePath));
ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(bytes);
byte[] bytK1 = getKeyByStr(sKey);
Cipher cipher = getCipher(bytK1, Cipher.DECRYPT_MODE);
OutputStream out = new FileOutputStream(targetPath);
CipherOutputStream cipherOutputStream = new CipherOutputStream(out, cipher);
IoUtil.copy(byteArrayInputStream, cipherOutputStream);
IoUtil.close(byteArrayInputStream);
IoUtil.close(out);
IoUtil.close(cipherOutputStream);
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
/**
* 文件加密流
* @param bytes 字节数组
* @return javax.crypto.CipherInputStream
* @throws InvalidKeySpecException 加密
* @throws NoSuchPaddingException 解密报错
* @throws NoSuchAlgorithmException 加密报错
* @throws InvalidKeyException 验证Key异常
*/
public CipherInputStream getCipherInputStream(byte[] bytes) throws InvalidKeySpecException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(bytes);
CipherInputStream cipherInputStream = this.getCipherInputStream(byteArrayInputStream);
return cipherInputStream;
}
/**
* 文件加密流
* @param inputStream 文件输入流
* @return javax.crypto.CipherInputStream
* @throws InvalidKeySpecException 加密
* @throws NoSuchPaddingException 解密报错
* @throws NoSuchAlgorithmException 加密报错
* @throws InvalidKeyException 验证Key异常
*/
public CipherInputStream getCipherInputStream(InputStream inputStream) throws InvalidKeySpecException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
byte[] bytK1 = getKeyByStr(sKey);
Cipher cipher = getCipher(bytK1, Cipher.ENCRYPT_MODE);
CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
IoUtil.close(inputStream);
return cipherInputStream;
}
/**
* 获取文件的解密输入流
* @param sourcePath 原加密文件路径
* @return java.io.ByteArrayInputStream
*/
public InputStream getDecodeInputStream(String sourcePath) {
try {
String targetPath = getTempPath(sourcePath);
//解密
decryptFile(sourcePath, targetPath);
File targetFile = new File(targetPath);
FileInputStream fileInputStream = new FileInputStream(targetFile);
byte[] readBytes = IoUtil.readBytes(fileInputStream);
IoUtil.close(fileInputStream);
//关闭后才能删除临时文件 fileInputStream
delFile(targetPath);
ByteArrayInputStream arrayInputStream = IoUtil.toStream(readBytes);
return arrayInputStream;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 删除文件
* @param targetPath 需要删除的文件路径
*/
private void delFile(String targetPath){
File targetFile = new File(targetPath);
if (targetFile.exists()) {
boolean del = FileUtil.del(targetFile);
System.out.println("删除临时文件:" + del);
}
}
/**
* 获取解密临时文件路径
* @param path 加密文件路径
* @return 解密临时文件路径
*/
private String getTempPath(String path) {
int lastIndexOf = path.lastIndexOf('.');
String file_path = path.substring(0, lastIndexOf);
//拼接解密后的临时存储文件
String targetPath = file_path + UUID.randomUUID().toString().replaceAll("-","") + ".temp";
return targetPath;
}
//region Des
/**
* 得到密码类
*
* @param bytKey
* @param i ENCRYPT_MODE = 1 DECRYPT_MODE = 2
* @return
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
*/
public Cipher getCipher(byte[] bytKey, int i) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException {
DESKeySpec desKS = new DESKeySpec(bytKey);
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(desKS);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(i, sk);
return cipher;
}
public static byte[] getKeyByStr(String str) {
byte[] bRet = new byte[str.length() / 2];
for (int i = 0; i < str.length() / 2; ++i) {
Integer itg = new Integer(16 * getChrInt(str.charAt(2 * i)) + getChrInt(str.charAt(2 * i + 1)));
bRet[i] = itg.byteValue();
}
return bRet;
}
public static int getChrInt(char chr) {
int iRet = 0;
if (chr == "0".charAt(0)) {
iRet = 0;
}
if (chr == "1".charAt(0)) {
iRet = 1;
}
if (chr == "2".charAt(0)) {
iRet = 2;
}
if (chr == "3".charAt(0)) {
iRet = 3;
}
if (chr == "4".charAt(0)) {
iRet = 4;
}
if (chr == "5".charAt(0)) {
iRet = 5;
}
if (chr == "6".charAt(0)) {
iRet = 6;
}
if (chr == "7".charAt(0)) {
iRet = 7;
}
if (chr == "8".charAt(0)) {
iRet = 8;
}
if (chr == "9".charAt(0)) {
iRet = 9;
}
if (chr == "A".charAt(0)) {
iRet = 10;
}
if (chr == "B".charAt(0)) {
iRet = 11;
}
if (chr == "C".charAt(0)) {
iRet = 12;
}
if (chr == "D".charAt(0)) {
iRet = 13;
}
if (chr == "E".charAt(0)) {
iRet = 14;
}
if (chr == "F".charAt(0)) {
iRet = 15;
}
return iRet;
}
//endregion
public static void main(String[] args) {
String sp = "E:\\文件加解密\\原始文件.docx";//原始文件
String dp = "E:\\文件加解密\\加密文件.docx";//加密后文件
String dp2 = "E:\\文件加解密\\解密文件.docx";//解密后文件
FileEncryption fileEncrypter = new FileEncryption();
//文件加密
fileEncrypter.encryptFile(sp,dp);
//文件解密
fileEncrypter.decryptFile(dp,dp2);
}
}