• lazarus在linux arm64使用SQLite数据加密的方法


    最近准备使用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 = ''--取消密码
  • 相关阅读:
    .Net中获取打印机的相关信息
    如何在windows server 2008上配置NLB群集
    jvm分析内存泄露
    JVM调优
    线程池工作队列饱和策略
    线程池的处理流程:
    Java的Executor框架和线程池实现原理(转)
    线程池实现原理详解:
    futer.get()(如果任务没执行完将等待)
    sql注入
  • 原文地址:https://www.cnblogs.com/qiufeng2014/p/16513905.html
Copyright © 2020-2023  润新知