由于工作需要,最近一周以来研究sqlite数据库文件的解密方法。最终采用sqlcipher工具进行解密。由于sqlcipher的实现大多是支持android的,修改为纯java平台下的代码有难度,因此选择了通过sqlcipher脚本执行解密的方案。从调研到最终发布,共尝试了ubuntu,windows8, centos7这三种系统下的解密。
- sqlcipher解密命令:
>>sqlcipher test.db //连接数据库
>>pragma key = "123"; //密钥
>>.tables //查看当前数据库下的所有表
- ubuntu:
1.sqlcipher软件安装。
apt-get install sqlcipher 即可完成。
2.编写.sh脚本,通过附加数据库的方式导出解密后的数据库。
#!/bin/sh
#文件路径
path=$1;#文件名
fileName=$2#密钥
key=$3;#导出文件名
outName=$4echo "=======开始解密=========";
echo "输入参数为:"${path}" "${fileName}" "${key}" "${outName}temp="\""${path}${outName}".db""\"";
temp2="('"${outName}"')"; #echo "导出文件路径:"${temp};#如果导出文件已存在,则删除
outPath=${path}${outName}".db"; if [ -f $outPath ] then echo "导出文件已存在,将会覆盖!"; rm -rf $outPath; fi#执行sqlcipher命令
echo "开始执行sqlcipher命令" sqlcipher ${path}${fileName} << EOF; PRAGMA key = ${key}; attach database ${temp} as ${outName} key ''; select sqlcipher_export ${temp2}; detach database ${outName}; EOF echo "=======解密完成=======";- windows8
1.下载sqlcipher.exe文件。
2.编写.bat脚本,导出解密后的数据库
off
::文件路径 set filePath=%1::文件名
set fileName=%2::密钥
set key=%3::导出文件名
set outName=%4::sqlcipher.exe文件的路径
set exePath=%5echo ===============STARTING DECRYPT=============
echo Input_Params:%filePath% %fileName% %key% %outName% %exePath% set temp='%filePath%%outName%.db' set temp2=('%outName%') echo Output_File_Path:%temp%::如果导出文件已存在,则删除
set outPath=%filePath%%outName%.db if exist %outPath% ( echo Output File is Exist, Will Overrite It! del %outPath% )::执行sqlcipher命令
echo Run the Sqlcipher Commands echo Current_Database:%filePath%%fileName%%exePath% %filePath%%fileName% "PRAGMA key = %key%;attach database %temp% as %outName% key '';select sqlcipher_export %temp2%;detach database %outName%;"
echo ================FINISH DECRYPT============== exit;- centos7
1.下载sqlcipher源码,编译之后会在sqlcipher文件夹下生成可执行文件sqlcipher.sh文件。
% git clone git://github.com/sqlcipher/sqlcipher.git% cd sqlcipher% ./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"% make
2.测试
./sqlcipher test.db
其余见sqlcipher解密命令
- java代码中调用.sh或.bat脚本
linux环境:
public static void execLinux(String cmd) throws Exception {
String[] cmdA = { "/bin/sh", "-c", cmd }; Process process = Runtime.getRuntime().exec(cmdA); process.waitFor(); // 获取返回结果 LineNumberReader br = new LineNumberReader(newInputStreamReader(process.getInputStream(),"UTF-8"));
String line; while ((line = br.readLine()) != null) { log.info(line); } }
windows环境:
public static void execWindows(String cmd) throws Exception {
Process process = Runtime.getRuntime().exec("cmd.exe /c start /b " + cmd); process.waitFor(); // 获取返回结果 LineNumberReader br = new LineNumberReader(newInputStreamReader(process.getInputStream(),"UTF-8"));
String line; while ((line = br.readLine()) != null) { log.info(line); } }