C# + SQLiteExpert 进行(cipher)加密数据库开发+Costura.Fody 清爽发布

news2024/11/17 13:51:00

      一:让 SQLiteExpert  支持(cipher)加密数据库

         SQLiteExpert  作为SQlite 的管理工具,默认不支持加密数据库的,使其成为支持(cipher)加密数据库的管理工具,需要添加e_sqlcipher.dll (复制到SQLiteExpertPro32/64.exe 同级目录即可,从哪里来的这个问题:你可以直接往后面下载链接下,也可以跟随文章知道从哪里来的。最好是知道从哪里来的,也许我放链接的版本在未来有新版本更替,我也就不更新下载链接了。),并在其设置里面进行勾选就能激活加密数据库支持。如下图所示(几个关键点已经标记),需要注意的是SQLiteExpert  32位/64位需要与e_sqlcipher.dll 32位/64位匹配,否则在32位版的SQLiteExpert  是看不到64位的e_sqlcipher.dll。

加入成功后,打开或者新建数据库都有加密选项

(新建数据库)

(打开加密数据库)

这样到此可以完整的处理了SQLiteExpert 支持加密

        由于SQLiteExpert 只有windows 版本,linux 平台的cipher加密支持库也就不打包了。对于跨平台的SQLite gui 也许类似,上传的压缩包就只有windows平台dll。

下载链接在顶部,压缩包结构如下:

二. .Net C# 连接(cipher)加密的SQlite数据库

nuget

1、SQLitePCLRaw.bundle_e_sqlcipher

2、Microsoft.Data.Sqlite

3、Costura.Fody (如果不需要考虑发布洁癖(单文件,全部外围DLL聚合),就没必要。)

直接debug,生成一堆内容,我随便建立了个VS 工程(sqlitedemo) debug目录大致如下:

runtime 内容如下:(也就是各种平台的(cipher)sqlite lib),前面的e_sqlcipher.dll取材就是从这里取得。

debug 生成的很多,也就是刚才说的发布生成洁癖的问题,如果你在意,发布时候选择输出好平台,runtime可以自动减少,但是依旧会生成其他dll。

那就采用Costura.Fody

编辑项目内 FodyWeavers.xml 文件(nuget过了会自动生成该文件),文件内容修改如下:

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <Costura >
    <Unmanaged64Assemblies>
      e_sqlcipher
      e_sqlite3
    </Unmanaged64Assemblies>
    <Unmanaged32Assemblies>
      e_sqlcipher
      e_sqlite3
    </Unmanaged32Assemblies>
  </Costura>
</Weavers>

再编辑 解决方案文件(右边第一箭头那里双击)

主要语句加入 (我选择的x64版本的Exe)

 <RuntimeIdentifier>win-x64</RuntimeIdentifier>

        这样,右键点击 解决方案->重新生成解决方案 (这里要注意,要重新整个解决方案才行。更改解决方案文件,直接debug会有问题。)

        最终生成输出内容如下:

其他乱七八糟的dll没有了,清爽吧?! 

再来看相关C# 连接Sqlite 操作的代码:先上SqliteHelper,顺便也推荐一下 Cody AI生成的,我用了很长时间,免费且好用(面向编程)。

    public class SQLiteHelper
    {
        private readonly string _connectionString;

        public SQLiteHelper(string dbPath, string password = null)
        {
            var builder = new SqliteConnectionStringBuilder
            {
                DataSource = dbPath,
                Mode = SqliteOpenMode.ReadWriteCreate
            };

            if (!string.IsNullOrEmpty(password))
            {
                builder.Password = password;
            }

            _connectionString = builder.ConnectionString;
        }

        public int ExecuteNonQuery(string sql, List<SqliteParameter> parameters = null)
        {
            using (var connection = new SqliteConnection(_connectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = sql;
                    if (parameters != null)
                    {
                        command.Parameters.AddRange(parameters);
                    }
                    return command.ExecuteNonQuery();
                }
            }
        }

        public T ExecuteScalar<T>(string sql, List<SqliteParameter> parameters = null)
        {
            using (var connection = new SqliteConnection(_connectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = sql;
                    if (parameters != null)
                    {
                        command.Parameters.AddRange(parameters);
                    }
                    var result = command.ExecuteScalar();
                    return (T)Convert.ChangeType(result, typeof(T));
                }
            }
        }

        public List<T> ExecuteQuery<T>(string sql, List<SqliteParameter> parameters = null) where T : new()
        {
            var result = new List<T>();
            using (var connection = new SqliteConnection(_connectionString))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = sql;
                    if (parameters != null)
                    {
                        command.Parameters.AddRange(parameters);
                    }

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var item = new T();
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                var property = typeof(T).GetProperty(reader.GetName(i), BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                                if (property != null && !reader.IsDBNull(i))
                                {
                                    property.SetValue(item, Convert.ChangeType(reader.GetValue(i), property.PropertyType));
                                }
                            }
                            result.Add(item);
                        }
                    }
                }
            }
            return result;
        }

        public void ExecuteTransaction(Action<SqliteConnection> action)
        {
            using (var connection = new SqliteConnection(_connectionString))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    try
                    {
                        action(connection);
                        transaction.Commit();
                    }
                    catch
                    {
                        transaction.Rollback();
                        throw;
                    }
                }
            }
        }
    }
}

调用如下:

SQLiteHelper 构造函数,第一个参数数据库路径文件全名,第二个参数数据库密码

   SQLiteHelper SLH = new SQLiteHelper("D:\\Manage\\Documents\\db", "TEST");
   const int batchSize = 100000;
   const string insertSql = "INSERT INTO Student (F_ID, F_Name) VALUES (@F_ID, @F_Name)";

   SLH.ExecuteTransaction(connection =>
   {
       using var command = connection.CreateCommand();
       command.CommandText = insertSql;
       command.Parameters.Add("@F_ID", SqliteType.Text);
       command.Parameters.Add("@F_Name", SqliteType.Text);

       for (int i = 0; i < batchSize; i++)
       {
           command.Parameters["@F_ID"].Value = Guid.NewGuid().ToString();
           command.Parameters["@F_Name"].Value = $"John{i}";
           command.ExecuteNonQuery();
       }
   });

密码错误则在这里报错:

这样既可以C# 开发加密数据库又可以在外部用外部工具直接编辑加密数据库的环境就达成了。

后话:

        选择SQLiteExpert 是界面要黑一点,可能不是最好用的,但黑色看起来眼睛舒服一点,欢迎推荐一些。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2172338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

服务器端请求伪造(SSRF)漏洞解析

免责申明 本文仅是用于学习检测自己搭建的靶场环境有关SSRF的原理和攻击实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法规内…

828华为云征文|华为云Flexus云服务器X实例搭建部署H5美妆护肤分销商城、前端uniapp

准备国庆之际&#xff0c;客户要搭个 H5 商城系统&#xff0c;这系统好不容易开发好啦&#xff0c;就差选个合适的服务器上线。那可真是挑花了眼&#xff0c;不知道哪款性价比高呀&#xff01;就像在琳琅满目的选择前。最终慧眼识珠&#xff0c;选择了华为云 Flexus X。至于为什…

嵌入式学习--数据结构+算法

嵌入式学习--数据结构算法 数据结构 1.1数据 1.2逻辑结构 1.3存储结构 1&#xff09;顺序存储结构 2&#xff09;链式存储结构 1.4操作&#xff08;数据的运算&#xff09; 算法 2.1算法与程序 2.2算法与数据结构 2.3算法的特性 2.4如何评价一个算法的好坏&#xff1f; 2.5时间…

在IDEA中构建Jar包,安装Jar包到Maven仓库并在Maven项目中使用

文章目录 0. 关于本文1. IDEA构建Jar包1.1 准备一份Java代码&#xff08;就是你要构建工件的代码&#xff09;1.2 进行如下步骤构建工件 2. 关于Maven3. 将Jar包安装到Maven仓库4. 使用安装的Jar包依赖 0. 关于本文 本文内容&#xff1a; 借助IDEA构建Jar包将Jar包安装到Mave…

设计模式之门面(Facade)模式

前言 在组建构建过程中&#xff0c;某些接口之间直接的依赖常常会带来很多问题、甚至跟本无法实现。采用添加一层&#xff08;间接&#xff09;稳定接口&#xff0c;来隔离本来互相紧密关联的接口是一种常见的解决方案 定义 “接口隔离” 模式。为子系统中的一组接口提供一个一…

【北京二号卫星】

北京二号卫星 北京二号卫星是中国自主研制的高分辨率遥感卫星之一&#xff0c;具有多方面的特点和广泛的应用价值。以下是对北京二号卫星的详细介绍&#xff1a; 一、基本信息 名称&#xff1a;北京二号类型&#xff1a;民用商业遥感卫星星座组成&#xff1a;由三颗高分辨率卫…

【PDCCH(一)】

LTE/NR中&#xff0c;采用了OFDM正交频分复用方式&#xff0c;也就是在频域上使用多个子载波&#xff0c;这些子载波互相正交&#xff1b;在时域上采用帧结构的方式&#xff0c;用不同的帧结构去区分不同的用户&#xff0c;不同的资源&#xff0c;信道等等。 所以我们常常把时间…

校园外卖系统SpringBoot免费分享

今天我们分享一个非常实用的校园外卖系统&#xff0c;基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的瑞吉外卖案例项目&#xff0c;经过站长的进一步改进和优化&#xff0c;提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue…

web前端-CSS引入方式

一、内部样式表 内部样式表(内嵌样式表)是写到html页面内部,是将所有的 CSS 代码抽取出来,单独放到一个<styie>标签中。 注意: ① <style>标签理论上可以放在 HTML文档的任何地方&#xff0c;但一般会放在文档的<head>标签中 ② 通过此种方式&#xff0c;可…

【多样化的思想】基于执行档案的测试

下面我们讨论另一种关于多样性的观点。我们知道&#xff0c;对被测对象而言&#xff0c;测试输入空间代表的是各种可能的外部环境条件。如果两个测试输入点距离比较远&#xff0c;说明在这两个点上&#xff0c;被测对象所面对的外部环境条件很不一样&#xff0c;所以我们说&…

RabbitMQ的高级特性-消息确认机制

对于RabbitMQ发送消息到消费端的可靠性保障 引入&#xff1a;发送者发送消息后&#xff0c;到达消费端之后会出现一下两种情况&#xff1a; ①消息处理成功 ②消息处理异常 RabbitMQ向消费者发送消息之后, 就会把这条消息删掉, 那么第两种情况, 就会造成消息丢失&#xff0…

fmql之字符驱动设备(3)-并发与竞争

学会使用设备树后&#xff0c;要学习linux驱动编写中容易出现的”并发与竞争“。 代码是在之前代码的基础上进行修改。 并发与竞争 &#xff08;本部分来自于正点原子pdf&#xff09; 什么是并发与竞争&#xff0c;为什么会出现并发与竞争&#xff1a; 要保护的内容是&#…

基于TSN的实时通信网络延迟评估技术

论文标题&#xff1a;A TSN-based Technique for Real-Time Latency Evaluation in Communication Networks 作者信息&#xff1a; Alberto Morato, Claudio Zunino, Manuel Cheminod, Stefano Vitturi&#xff0c;来自意大利国家研究委员会&#xff0c;CNR-IEIIT。电子邮件:…

深度学习实战TT100K中国交通标志检测【数据集+YOLOv5模型+源码+PyQt5界面】

AI深度学习TT100k交通标志识别 文章目录 研究背景代码下载链接一、效果演示1.1 图像演示1.2 视频演示 二、技术原理2.1 整体流程2.2 TT100K中国交通标志数据集介绍2.3 YOLOV5 TT100K中国交通标志检测原理2.3.1 概述2.3.2 输入层2.3.3 Backbone层2.3.4 Backbone层2.3.5 Head层 2…

【人人保-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【时时三省】(C语言基础)指针笔试题6

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 笔试题6 首先aa&#xff3b;2&#xff3d;&#xff3b;5&#xff3d;是二维数组 也就是说它有两行第一行是1 2 3 4 5 第二行是6 7 8 9 10 然后&aa取出的数组的地址 &aa1就直接跳到第…

第1章 C++初识

1.1 编写第一个C程序 1.打开Visual Studio点击"创建新项目" 2.点击"空项目"&#xff0c;并点击"下一步" 3.设置"项目名称"并"设置地址" 4.打开项目后&#xff0c;右击"源文件"并选择"添加"的"新建…

国产操作系统(统信UOS)网络安全等级保护基础安全加固

统一操作系统UOS是由多家企业共同打造的中文国产操作系统。 一、设置口令复杂度策略和有效期 首先安装libpam-pwquality依赖包 口令复杂度策略通过libpam-pwquality依赖包进行设置 依赖包的安装命令&#xff1a;sudo apt-get install libpam-pwquality。 依赖包的查看方式执…

新茶饮卷出海,本土化成胜败关键

爱扬格说&#xff1a;“在那海水酣睡的宫殿里&#xff0c;铺满了多少奇珍异宝。”如今&#xff0c;新茶饮品牌正掀起出海狂潮&#xff0c;挖掘来自海外市场的财富机会。 近日&#xff0c;茶百道股价实现十连涨。消息面上&#xff0c;公司在韩国首尔建大站新店正式对外营业。根…

复现 BEVfusion bug集合(4090d)

目录 写在前面的话Bug 汇总1. python版本2. cuda版本3. mmdet3d版本4. mmcv版本5. mmdet版本 后期工作&#xff08;看到numpy说明成功一半&#xff09;6. numpy版本7. timm安装8. yapf 版本 写在前面的话 主要的问题还是mmcv库的问题&#xff0c;这个版本维护太差了&#xff0…