本文主要是自己在实际用的过程记录,如发现理解错误,欢迎指正。
1https://github.com/sqlcipher/sqlcipher 下载源代码
2 # ./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC"
3 # make
make: tclsh: Command not found
make: *** [fts5.c] Error 127
make: *** Waiting for unfinished jobs....
#./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" --disable-tcl
# make -j 16
cat parse.h /home/work/guoli/sqlcipher-master/src/vdbe.c | tclsh /home/work/guoli/sqlcipher-master/tool/mkopcodeh.tcl >opcodes.h
/bin/sh: tclsh: command not found
make: *** [opcodes.h] Error 127
--------------------------------------------------------------------------------
4 安装tcl
http://www.tcl.tk/software/tcltk/
# tar -xvzf tcl8.6.8-src.tar.gz
#cd tcl8.6.8/unix
#./configure --prefix=/user/local/tcl
# make
#sudo make install
# sudo ln -s /user/local/tcl/bin/tclsh8.6 /bin/tclsh
--------------------------------------------------------------------------------
重复步骤2
报错:
sqlite3.c:16702:3: error: unknown type name ‘sqlite3_mutex’
5 怀疑需要安装 sqlite
http://124.205.69.135/files/11450000061AF698/www.sqlite.org/2017/sqlite-autoconf-3210000.tar.gz
#tar -xvxf sqlite-autoconf-3210000.tar.gz
#cd sqlite-autoconf-3210000/
#./configure
#make
#sudo make install
--------------------------------------------------------------------------------
重复步骤2
编译通过
-------------------------------- 测试 --------------------------------------
加密已有的数据库(参考http://blog.csdn.net/sskicgah/article/details/37502433)
1.先用sqlite打开db文件
sqlite3 test.db
2.把数据导成sql格式
sqlite> .output test.sql
sqlite> .dump
sqlite> .exit
3.加密 //加密的过程是生成了一个新的有密码的数据库
./sqlcipher test2.db #创建一个新的db文件
sqlite> PRAGMA key = 'test'; #设置密码
sqlite> .read test.sql #导入数据
sqlite> .exit #退出
把加密过的文件放在Windows 下用navicat premium 直接查看,加密成功。
但是用sqlcipher.exe输入设置的密码,确不能打开
经检查:sqlcipher.exe 是2.1版本的。加密用的是基于3.20.1版本,不同的版本生成的db文件可能不兼容
4. 解密
#./sqlcipher test2.db
sqlite> PRAGMA KEY='test';//需先输密码解密再进行其他操作
sqlite> .schema
CREATE TABLE xxxx ... ...
# ./sqlcipher test2.db
sqlite> .schema
Error: file is not a database
(还以为把密码设置成空,就能把密码抹去,原来不是这么一回事)
#./sqlcipher test2.db
sqlite> PRAGMA key = 'test';//去掉密码的过程是生成了一个新的没有密码的数据库
sqlite> ATTACH DATABASE 'text.db' AS plaintext KEY '';
sqlite> SELECT sqlcipher_export('plaintext');
sqlite> DETACH DATABASE plaintext;
sqlite> .exit
#./sqlcipher text.db //查看新库
sqlite> .schema
CREATE TABLE xxxx
5 修改密码
# ./sqlcipher test2.db
sqlite> PRAGMA KEY='test';
sqlite> PRAGMA rekey = 'newkey';
sqlite> .exit
借鉴了很多网友的帖子,多谢~
--------------------------------------------------------------------------------
其他报错:
./.libs/libsqlcipher.so: undefined reference to `HMAC_CTX_new'
./.libs/libsqlcipher.so: undefined reference to `HMAC_CTX_free'
collect2: error: ld returned 1 exit status
make: *** [sqlcipher] Error 1
交叉编译sqlcipher
https://www.cnblogs.com/bbqzsl/p/7736060.html
--------------------------------------------------------------------------------
SQLCipher主要API
(
https://www.zetetic.net/sqlcipher/sqlcipher-api/)
PRAGMA key
Example 1: Passphrase with Key Derivation
sqlite> PRAGMAkey = 'passphrase';
Example 2: Raw Key Data (Without KeyDerivation)
sqlite> PRAGMA key = "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
PRAGMA cipher
sqlite> PRAGMA key = 'blue valentines';
sqlite> PRAGMA cipher = 'aes-256-cfb';
PRAGMA kdf_iter
sqlite> PRAGMA key = 'blue valentines';
sqlite> PRAGMA kdf_iter = '10000';
PRAGMA cipher_default_kdf_iter
./sqlcipher sqlcipher2.0.db
sqlite> PRAGMA cipher_default_kdf_iter = 4000;
sqlite> PRAGMA key = 's3cr37';
PRAGMA cipher_page_size
sqlite> PRAGMA KEY = 'testkey';
sqlite> PRAGMA cipher_page_size = 4096;
PRAGMA cipher_default_page_size
$ ./sqlcipher foo.db
sqlite> PRAGMA key = 'foo';
sqlite> PRAGMA cipher_page_size = 4096;
sqlite> CREATE TABLE t1(a,b);
sqlite> INSERT INTO t1(a,b) values('one for the money', 'two for the show');
sqlite> .q
$ ./sqlcipher bar.db
sqlite> PRAGMA cipher_default_page_size = 4096;
sqlite> PRAGMA key = 'bar';
sqlite> ATTACH DATABASE 'foo.db' as foo KEY 'foo';
sqlite> SELECT count(*) FROM foo.t1;
PRAGMA rekey
sqlite> PRAGMA key = 'old passphrase';
sqlite> PRAGMA rekey = 'new passphrase';
PRAGMA cipher_use_hmac
sqlite> PRAGMA key = 'blue valentines';
sqlite> PRAGMA cipher_use_hmac = OFF;
PRAGMA cipher_default_use_hmac
./sqlcipher sqlcipher2.0.db
sqlite> PRAGMA key = 's3cr37'; -- opens using default setting, with HMAC on
sqlite> PRAGMA cipher_default_use_hmac = OFF;
sqlite> ATTACH DATABASE '1.1.x.db' AS remote key 's3cr37'; -- next open operation, the default for HMAC is off, and this database
ATTACH
Example 1: Attach an Encrypted Database to aPlaintext Database
$ ./sqlcipher plaintext.db
sqlite> ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'testkey';
Example 2: Attach an Encrypted Database usinga Hex Key
$ ./sqlcipher plaintext.db
sqlite> ATTACH DATABASE 'test2.db' AS db2 KEY "x'10483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
Example 3: Attach an Plaintext Database to anEncrypted Database
$ ./sqlcipher encrypted.db
sqlite> ATTACH DATABASE 'plaintext.db' AS plaintext KEY ''; -- empty key will disable encryption
sqlcipher_export()
Example 1: Encrypt a Plaintext Database
$ ./sqlcipher plaintext.db
sqlite> ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'testkey';
sqlite> SELECT sqlcipher_export('encrypted');
sqlite> DETACH DATABASE encrypted;
Example 2: Decrypt a SQLCipher database to aPlaintext Database
$ ./sqlcipher encrypted.db
sqlite> PRAGMA key = 'testkey';
sqlite> ATTACH DATABASE 'plaintext.db' AS plaintext KEY ''; -- empty key will disable encryption
sqlite> SELECT sqlcipher_export('plaintext');
sqlite> DETACH DATABASE plaintext;
Example 3: Convert from a 1.1.x to 2.0Database with HMAC
$ ./sqlcipher 1.1.x.db
sqlite> PRAGMA key = 'testkey';
sqlite> PRAGMA cipher_use_hmac = OFF; -- disable HMAC on main database
sqlite> ATTACH DATABASE '2.0.db' AS newdb; -- new database will use default HMAC setting, ON, with same key as the main database
sqlite> SELECT sqlcipher_export('newdb');
sqlite> DETACH DATABASE newdb;
Example 4: Changing Cipher Settings
$ ./sqlcipher encrypted.db
sqlite> PRAGMA key = 'testkey';
sqlite> ATTACH DATABASE 'newdb.db' AS newdb KEY 'newkey';
sqlite> PRAGMA newdb.cipher_page_size = 4096;
sqlite> PRAGMA newdb.cipher = 'aes-256-cfb';
sqlite> PRAGMA newdb.kdf_iter = 10000;
sqlite> SELECT sqlcipher_export('newdb');
sqlite> DETACH DATABASE newdb;
PRAGMA cipher_migrate
> ./sqlcipher 2xdatabase.db
> PRAGMA key = 'YourKeyGoesHere';
> PRAGMA cipher_migrate;
PRAGMA cipher_profile
$ ./sqlcipher example.db
sqlite> PRAGMA cipher_profile='sqlcipher.log';
sqlite> CREATE TABLE t1(a,b);
sqlite> INSERT INTO t1(a,b) VALUES('one for the money', 'two for the show');
sqlite> PRAGMA cipher_profile=off;
PRAGMA cipher_add_random
PRAGMA cipher_add_random = "x'deadbaad'";
PRAGMA cipher_provider
PRAGMA cipher_provider_version
PRAGMA cipher_version
$ ./sqlcipher example.db
sqlite> PRAGMA cipher_version;
3.3.1
sqlite3_key() and sqlite3_key_v2()
/*
** Specify the key for an encrypted database. This routine should be
** called right after sqlite3_open().
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key, and the length of the key in bytes */
);
int sqlite3_key_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The key */
);
sqlite3_rekey() sqlite3_rekey_v2()
/*
** Change the key on an open database. If the current database is not
** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public releasejavascript:noop()
** of SQLite.
*/
int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key, and the length of the key in bytes */
);
int sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);