最近准备使用lazrus开发SQLite小应用,发现在linux aarch64下没找到适合的libsqlite3.so加密版本,需然网上有wxsqlite等开源版本,但编译不成功,最终发现开源的SQLite3 Multiple Ciphers能满足使用,最主要是编译so很简单,适合新手根据不同平台自行编译加密的so文件。
SQLite3MultipleCiphers下载网址:
https://github.com/utelle/SQLite3MultipleCiphers/
下载解压后,在终端执行以下2行命令就能生成libsqlite3.so,建议将libsqlite3.so拷贝到工程的文件夹。
gcc -O2 -s -shared -fPIC -c sqlite3mc.c
gcc -O2 -s -shared -fPIC -o libsqlite3.so sqlite3mc.o
发现linux x86_64下不能按以述方法编译,经测试使用以下方法就可以编译:
linux x86_64编译so步骤:
1、安装sudo apt install -y autoconf 如已安装请跳过
2、autoreconf
3、配置:./configure --prefix =/home/sqlite3/ (注:=后面是sqlite的安装路径,可以自己新建一个文件夹存放)
4、编译,安装
命令:make clean;make;make install (注:make clean是为了清除以前的编译文件,make是在编译,make install是安装)
安装完成后,在安装目录下可以看到生成了lib,include
使用Zeos控件时要注意指定libsqlite3.so和位置(必须使用绝对路径),可以参考以下代码:
ZConnection1.LibraryLocation:=ExtractFilePath(Application.ExeName)+'libsqlite3.so';
如需加密SQLite库,只需在生成时ZConnection1.Password加上密码就可以。
ZConnection1.DisConnect;
ZConnection1.Protocol:='sqlite-3';
ZConnection1.LibraryLocation:=ExtractFilePath(Application.ExeName)+'libsqlite3.so';
ZConnection1.Properties.Add('encrypted=yes');
ZConnection1.Database:='demo.db3';
ZConnection1.Password:='123asd';
ZConnection1.Connect;
ZQuery1.SQL.Text := 'CREATE TABLE hardware (id INTEGER PRIMARY KEY, compname VARCHAR(30), username VARCHAR(30), model VARCHAR(30))';
ZQuery1.ExecSQL;
ZQuery1.SQL.Text := 'CREATE INDEX sHardware ON hardware(compname)';
ZQuery1.ExecSQL;
ZQuery1.SQL.Text := 'INSERT INTO hardware(id, compname, username, model) VALUES (1, "AMD8537", "OMonge", "Gigabyte");';
ZQuery1.ExecSQL;
ZConnection1.Disconnect;
打开SQLite数据库,如果数据库没设置密码,则为数据库设置密码:
procedure RekeyDB(conn: TZConnection; pwd: string);
var
db: Pointer;
i: integer;
begin
if not conn.Connected Then conn.Connect;
db := (conn.DbcConnection as IZSQLiteConnection).GetConnectionHandle;
i := (conn.DbcConnection as IZSQLiteConnection).GetPlainDriver.ReKey
(db, PChar(pwd), Length(pwd));
If (i <> 0) then // 函数正常执行返回0,否则
begin
// xxxxxxx
end;
end;
function IsSQLite3File(const FileName: TFileName): boolean;
var F: THandle;
Header:array [0..15] of char ;
begin
F := FileOpen(FileName,fmOpenRead or fmShareDenyNone);
if F= THandle(-1) then
result := false else
begin
FileRead(F,Header,15);
if Header='SQLite format 3' then result:=true
else result:=false;
FileClose(F);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ZConnection1.Disconnect;
ZConnection1.Protocol:='sqlite-3';
ZConnection1.LibraryLocation:=ExtractFilePath(Application.ExeName)+'libsqlite3.so';
ZConnection1.Properties.Clear;
ZConnection1.Properties.Add('encrypted=yes');
ZConnection1.Properties.Add('controls_cp=CP_UTF8');
ZConnection1.Properties.Add('AutoEncodeStrings=True');
ZConnection1.Database:='demo.db3';
if IsSQLite3File('demo.db3') then
RekeyDB(ZConnection1,'123asd') //未加密,则设置数据库密码
else
begin
ZConnection1.Password:='123asd';//已加密
ZConnection1.connect;
end;
end;
执行上面的代码后就能生成加密的demo.db3。
设置或取消数据库密码:
uses ZDbcSqLite---要加上这个单元
procedure RekeyDB(conn: TZConnection; pwd: string);
var
db: Pointer;
i: integer;
begin
db := (conn.DbcConnection as IZSQLiteConnection).GetConnectionHandle;
i := (conn.DbcConnection as IZSQLiteConnection).GetPlainDriver.ReKey
(db, PChar(pwd), Length(pwd));
If (i <> 0) then // 函数正常执行返回0,否则
begin
// xxxxxxx
end;
end;
使用方法:
procedure TForm1.Button2Click(Sender: TObject);
begin
ZConnection1.Disconnect;
ZConnection1.Protocol:='sqlite-3';
ZConnection1.LibraryLocation:=ExtractFilePath(Application.ExeName)+'libsqlite3.so';
ZConnection1.Properties.Clear;
ZConnection1.Properties.Add('encrypted=yes');
ZConnection1.Properties.Add('controls_cp=CP_UTF8');
ZConnection1.Properties.Add('AutoEncodeStrings=True');
ZConnection1.Database:='demo.db3';
ZConnection1.Password:='123asd';
ZConnection1.Connect;
RekeyDB(ZConnection1,'');//取消密码
end;
linux aarch64编译SQLite3命令行:
gcc shell.c sqlite3mc.c -lpthread -ldl -o sqlite3
linux x86_64 SQLite3命令行的编译:
autoreconf
mkdir build-gtk [or any other suitable name]
cd build-gtk
../configure
make
使用SQLite3命令行数据密码设置和取消的方法:
sqlite3 demo.db3 # 创建一个新的数据库
sqlite> PRAGMA key='123asd'; # 设置加密数据库的密码
ok # 显示 ok 说明设置密码成功
sqlite> create table help (id int, name text); # 创建一些数据
sqlite> .q # 退出数据库
sqlite3 demo.db3 # 再次进入数据库,相当于进入了一个已经加密的数据库
sqlite> .tab # 在不输入密码的情况下查看当前的表
Error: file is not a database # 不输入密码的情况下,解析数据库失败
sqlite> PRAGMA key = '123asd'; # 使用密码进行认证
ok # 输出 ok,说明认证成功
sqlite> .tab # 查看数据库中的表
help # 查看表成功,目前数据库中只有表 help
PRAGMA key = '123asd'--设置密码
PRAGMA rekey = ''--取消密码