最近准备使用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 = ''--取消密码