近期在做一个对数据安全要求比较高的软件,用户要求做到对接口、文件、以及数据库部分敏感字段进行加密。由于系统中文件内容比较敏感,用户要求除了客户其他人不能查看文件具体内容,包括运维人员和开发人员。
探讨
其实文件加密并不算太复杂。无非就是在用户上传文件的时候将文件内容读出加密写入后再存到服务器,然后用户下载的时候将内容读出然后解密再写入输出流即可。
简单实现
计算机数据内容是二进制,针对二进制最简单高效的修改是进行位运算,考虑加密以及解密,可以使用异或(^)计算,具体代码如下:
public static void main(String[] args) throws Exception{
// 加密解密秘钥
private static final int secretKey = 0xff;
// 文件内容加密
try (FileInputStream in = new FileInputStream("加密原文件.md");
FileOutputStream out = new FileOutputStream("加密后文件.md")){
int dataByte;
while ((dataByte = in.read()) != -1){
out.write(dataByte ^ secretKey);
}
}
// 文件内容解密
try (FileInputStream in = new FileInputStream("加密后文件.md");
FileOutputStream out = new FileOutputStream("解密后文件.md")){
int dataByte;
while ((dataByte = in.read()) != -1){
out.write(dataByte ^ secretKey);
}
}
}
JDK文件加解密
加密涉及到大文件加密过程,不能直接使用Cipher.doFinal(byte[] bytes)方法进行直接加密,超大文件会导致内存溢出。
Java已经帮我们解决了这一问题,通过文件加密流CipherInputStream和CipherOutputStream,使用这两个加密流我们可以实现使用不同的加密算法对文件加解密。
通过CipherInputStream加解密文件
CipherInputStream加密流是对Cipher和InputStream的包装,它在读取流的时候进行加密或者解密。
public static void encryptFile(String sourceFilePath, String destFilePath,