原因:最近在用Sqlite存储数据,因涉及数据安全,所以需要数据库加密,Sqlite库默认不带加密功能 目前已知的对 SQLite 加密的工具主要有「[SQLite Encryption Extension (SEE)]、[SQLiteEncrypt]、[SQLiteCrypt]、[SQLCipher],但是这里面仅有 SQLCipher 有免费版本。 所以自己有个方案,针对Sqlite无法就是限制不能直接查看,那就对文件进行加密,需要连接的时候进行文件解密就可以了,如果大神有更好的解决方案,请告知,谢谢!
package com.ts.tools;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import java.io.*;
/** 加密解密文件
* @author xhc
* @version 1.0.0
* @date 2022-10-31
*/
public class FileEnDe {
public static void main(String[] args) {
try {
//加密密码
String key="abcdefghijklmnop";
//FileEnDe.encryptFile("D:/test.db",key,true);
//FileEnDe.decryptFile("D:/test.db",key);
System.out.println(FileEnDe.isLocked("D:/sysDb.db"));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 加密db文件(理论可以加密任何文件)
* @param filePath 文件路径
* @param key16 加密密码(必须16位)
* @return boolean
* @throws Exception
*/
public static boolean encryptFile(String filePath,String key16,boolean isReadOnly){
FileOutputStream fos =null;
boolean bFlag=false;
try {
if(FileUtil.exist(filePath)) {
byte[] key = key16.getBytes();
//取文件名称含后缀
String fileName=FileUtil.getName(filePath);
//加密文件
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
FileInputStream fis = new FileInputStream(filePath);
String newFilePath=filePath+"_e";
fos=new FileOutputStream(newFilePath);
aes.encrypt(fis, fos, true);
fos.close();
//删除源文件,注意如果文件被使用会报:另一个程序正在使用此文件,进程无法访问
boolean isDel=FileUtil.del(filePath);
if(isDel){
//重命名加密文件为源文件
FileUtil.rename(new File(newFilePath),fileName,true);
//设置只读文件
if(isReadOnly) {
File f=new File(filePath);
f.setReadOnly();
}
}
bFlag=true;
}else{
throw new RuntimeException(filePath+" 文件不存在!");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IoUtil.close(fos);
}
return bFlag;
}
/**
* 解密Db库
* @param filePath 文件路径
* @param key16 加密密码(必须16位)
* @return boolean
* @throws Exception
*/
public static boolean decryptFile(String filePath,String key16){
boolean bFlag=false;
FileOutputStream fos =null;
try {
if(FileUtil.exist(filePath)) {
byte[] key = key16.getBytes();
//取文件名称含后缀
String fileName=FileUtil.getName(filePath);
//解密文件
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
FileInputStream fis = new FileInputStream(filePath);
String newFilePath=filePath+"_d";
fos = new FileOutputStream(newFilePath);
aes.decrypt(fis, fos, true);
//注意,解密之后 fos 并未关闭,请先关闭
fos.close();
//删除源文件,注意如果文件被使用会报:另一个程序正在使用此文件,进程无法访问
boolean isDel=FileUtil.del(filePath);
if(isDel){
//重命名加密文件为源文件
FileUtil.rename(new File(newFilePath),fileName,true);
}
bFlag=true;
}else{
throw new RuntimeException(filePath+" 文件不存在!");
}
} catch (FileNotFoundException e) {
throw new RuntimeException(filePath+" 文件不存在!");
}catch (Exception e){
throw new RuntimeException(e);
}finally {
IoUtil.close(fos);
}
return bFlag;
}
/**
* 文件是否占用(采用重命名的方式)
* @param filePath 文件路径
* @return boolean
*/
public static boolean isLocked(String filePath){
boolean bFlag=false;
String newFileName="";
String fileName="";
try {
if(FileUtil.exist(filePath)) {
// 采用重命名的方式,如果占用无法修改文件名称,如果未占用修改新的文件名称后再修改回来
fileName = FileUtil.getName(filePath);
newFileName = fileName + "_n";
FileUtil.rename(new File(filePath), newFileName, true);
}
} catch (Exception e) {
bFlag=true;
}finally {
//如果未占用修改新的文件名称后再修改回来
if(!bFlag) {
FileUtil.rename(new File(filePath+"_n"), fileName, true);
}
}
return bFlag;
}
}