相关文章推荐
傻傻的大熊猫  ·  QStringList ...·  1 年前    · 
安静的消炎药  ·  Hive UNION ...·  1 年前    · 
慷慨的水煮肉  ·  java.sql.timestamp ...·  1 年前    · 
豪情万千的铁板烧  ·  RestTemplate ...·  1 年前    · 

我们在使用 electron 开发时,使用了 better-sqlite3,但数据比较敏感,所以希望对数据进行加密,有两种方案:
1、对存储字段的内容进行加密;
2、对数据库文件进行加密;

方案一比较好理解,在加入数据的时候进行对称加密,取出数据后进行解密即可;
方案二则因为sqlite不支持加密功能(免费版不支持, 但提供了Sqlite Encrypt Extenssion),目前比较常见的做法应该是,better-sqlite3 + better-sqlite3-multiple-ciphers;

// 优缺点对比
1、方案一比较简单,但会侵入到业务逻辑里面;  
2、方案二比较复杂(e.g. 用的人少相关配套不是很完善,better-sqlite3-multiple-ciphers是21年才开源的npm包; 调试比较麻烦,例如我原本是通过vscode的 sqlite 拓展应用直接查询的,现在要先经过麻烦的解密步骤后才能进行查询),但对整个数据库文件进行加密,不需要入侵代码;    

方案一比较简单,这里不展开了。本文主要是讲下方案二的实践。

typeorm-better-sqlite-sqlcipher

better-sqlite3-multiple-ciphers用法比较简单,只要更换驱动即可。我使用的是 typeorm,代码如下:

const options = {
    type:'better-sqlite3',
    driver: require('better-sqlite3-multiple-ciphers'),
    database: path.join(app.getPath('userData'), `./db/${uid.toString()}.sqlite`),
    entities: [
      path.join(app.getAppPath(), './src/entity/*.js')
    prepareDatabase: db => {
      db.pragma(`cipher='sqlcipher'`)
      db.pragma(`legacy=4`) // sqlcipher 版本
      db.pragma(`key=sj123456`) // 密码

加密后的数据文件无法通过 sqlite3命令行或者其他数据库工具访问了。
但仍有一个问题,我们经常需要查询数据库进行问题查找,已加密的数据库如何在项目外进行解密呢?
我之前一直都是用的vscode的插件进行本地数据库查询,但现在加密后的数据库无法直接打开了。需要使用工具 sqlcipher 解密后再访问;

sqlcipher 解密工具

使用 macOS 的可以直接使用 brew 进行安装即可;
其他平台需要 clone 源码编译安装;

// 加密,将 wubiWords.db 加密后导出新的数据库 encrypted_wbwords.db
~ $ sqlcipher wubiWords.db
sqlite> ATTACH DATABASE 'encrypted_wbwords.db' AS wubiwords KEY 'xxxxxxxx';
sqlite> SELECT sqlcipher_export('wubiwords');
sqlite> DETACH DATABASE wubiwords;
sqlite> .exit
// 解密,将 encrypted_wbwords.db 设置为空密码后导出 decrypted_wbwords.db
$ ./sqlcipher encrypted_wbwords.db
sqlite> PRAGMA key = 'xxxxxxxx';
sqlite> ATTACH DATABASE 'decrypted_wbwords.db' AS encrypted_wbwords KEY '';  --空的密码不会加密数据库
sqlite> SELECT sqlcipher_export('encrypted_wbwords');
sqlite> DETACH DATABASE encrypted_wbwords;
sqlite> .exit

测试可以将 better-sqlite3-multiple-ciphers 加密过的数据库文件解密后正常查询。

1、typeorm是在typeorm@0.2.42版本才支持 key pragma,需要注意版本升级;
2、sqlcipher 版本问题;github.com/sqlcipher/s…

说实话,做完之后发现可能还是方案一直接加密内容可能会是更好的方案,nodejs这块生态还是不如移动端,相关的资料和控件比较少。

1、node-sqlcipher: github.com/journeyapps…
2、How to set options when using better-sqlite3 with sqlcipher? github.com/typeorm/typ…
3、Difference between sqlite and better-sqlite3 implementation: stackoverflow.com/questions/6…
4、Add new connection option to sqlite for SQLCipher: github.com/typeorm/typ…
5、Command Line Shell For SQLite: sqlite.org/cli.html#do…
7、使用 sqlcipher 加密解密 sqlite3 数据库:luowei.github.io/sqlite/1590…
8、PRAGMA Statements: www.sqlite.org/pragma.html

分类:
前端
标签: