SQLCipher 是一个基于 SQLite 的扩展,提供了透明的数据库加密功能。与普通 SQLite 不同,SQLCipher 在数据写入磁盘前自动加密,读取时自动解密,无需开发者手动处理加密逻辑。这使得它非常适合移动应用、桌面应用等需要本地数据加密的场景。

特性SQLCipher
开发语言C(原生 SQLite 扩展)
加密方式内置 AES-256 加密,透明化处理
API 兼容性完全兼容 SQLite API
跨平台支持原生支持多平台(iOS、Android、Web)

Node.js 操作 SQLCipher 的实现

在 Node.js 环境中操作 SQLCipher,我们可以使用sqlcipher包,它是 SQLCipher 的 Node.js 绑定。下面详细介绍如何在 Node.js 中使用 SQLCipher:

1. 安装依赖

首先需要安装sqlcipher包:

npm install sqlcipher
2. 基本操作示例

以下是一个完整的示例,展示了如何在 Node.js 中使用 SQLCipher 进行数据库操作:

const sqlcipher = require('sqlcipher');
sqlcipher.verbose();// 打开或创建数据库
const db = new sqlcipher.Database('encrypted.db');// 数据库操作封装为Promise
const execute = (db, sql, params = []) => {return new Promise((resolve, reject) => {db.run(sql, params, function(err) {if (err) {reject(err);} else {resolve(this);}});});
};const get = (db, sql, params = []) => {return new Promise((resolve, reject) => {db.get(sql, params, (err, row) => {if (err) {reject(err);} else {resolve(row);}});});
};const all = (db, sql, params = []) => {return new Promise((resolve, reject) => {db.all(sql, params, (err, rows) => {if (err) {reject(err);} else {resolve(rows);}});});
};// 初始化数据库
async function initDatabase() {try {// 打开数据库连接await new Promise((resolve, reject) => {db.open((err) => {if (err) {reject(err);} else {resolve();}});});// 设置加密密钥(非常重要!)await execute(db, `PRAGMA key = 'your-strong-password-here';`);await execute(db, `PRAGMA cipher_compatibility = 4;`);// 创建表await execute(db, `CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY,username TEXT NOT NULL,email TEXT UNIQUE NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP)`);console.log('数据库初始化完成');} catch (error) {console.error('数据库初始化失败:', error);throw error;}
}// 插入数据示例
async function insertUser(username, email) {try {const result = await execute(db, 'INSERT INTO users (username, email) VALUES (?, ?)', [username, email]);console.log(`插入用户成功,ID: ${result.lastID}`);return result.lastID;} catch (error) {console.error('插入用户失败:', error);throw error;}
}// 查询数据示例
async function getUsers() {try {const users = await all(db, 'SELECT * FROM users');return users;} catch (error) {console.error('查询用户失败:', error);throw error;}
}// 更新数据示例
async function updateUserEmail(userId, newEmail) {try {await execute(db, 'UPDATE users SET email = ? WHERE id = ?', [newEmail, userId]);console.log(`更新用户邮箱成功,ID: ${userId}`);} catch (error) {console.error('更新用户邮箱失败:', error);throw error;}
}// 删除数据示例
async function deleteUser(userId) {try {await execute(db, 'DELETE FROM users WHERE id = ?', [userId]);console.log(`删除用户成功,ID: ${userId}`);} catch (error) {console.error('删除用户失败:', error);throw error;}
}// 关闭数据库
async function closeDatabase() {try {await new Promise((resolve, reject) => {db.close((err) => {if (err) {reject(err);} else {resolve();}});});console.log('数据库已关闭');} catch (error) {console.error('关闭数据库失败:', error);throw error;}
}// 使用示例
async function runExample() {try {// 初始化数据库await initDatabase();// 插入数据const userId = await insertUser('john_doe', 'john@example.com');// 查询数据const users = await getUsers();console.log('所有用户:', users);// 更新数据await updateUserEmail(userId, 'john.doe@example.com');// 再次查询数据const updatedUsers = await getUsers();console.log('更新后的用户:', updatedUsers);// 删除数据await deleteUser(userId);// 最后查询数据const finalUsers = await getUsers();console.log('删除后的用户:', finalUsers);} catch (error) {console.error('操作失败:', error);} finally {// 关闭数据库连接await closeDatabase();}
}// 执行示例
runExample();

关键操作说明

1. 数据库加密设置
// 设置加密密钥
await execute(db, `PRAGMA key = 'your-strong-password-here';`);// 设置加密兼容性(版本4是最新的加密算法)
await execute(db, `PRAGMA cipher_compatibility = 4;`);

这两行代码非常关键,必须在打开数据库后立即执行。如果密钥不正确,后续的数据库操作将失败。

2. 安全注意事项
  1. 密钥管理:不要在代码中硬编码密钥,尤其是在生产环境中。可以使用环境变量、配置文件或密钥管理服务来存储密钥。

  2. 防止 SQL 注入:始终使用参数化查询(如上面示例中的?占位符),避免直接拼接 SQL 字符串。

  3. 数据库文件权限:确保数据库文件的访问权限设置正确,避免未授权访问。

3. 性能考虑

SQLCipher 的加密操作会带来一定的性能开销,通常比普通 SQLite 慢 10-20%。在性能敏感的应用中,可以考虑:

  1. 使用批量操作减少加密 / 解密次数
  2. 优化查询以减少不必要的数据处理
  3. 在内存中缓存频繁访问的数据
1. 备份加密数据库
async function backupDatabase() {try {const backupDb = new sqlcipher.Database('backup.db');await new Promise((resolve, reject) => {backupDb.open((err) => {if (err) {reject(err);} else {resolve();}});});// 设置备份数据库的密钥(必须与源数据库相同)await execute(backupDb, `PRAGMA key = 'your-strong-password-here';`);// 执行备份const backup = db.backup(backupDb);backup.step(1, (err, state) => {if (err) {console.error('备份失败:', err);} else if (state === 1) {console.log('备份完成');}backup.finish();backupDb.close();});} catch (error) {console.error('备份数据库失败:', error);throw error;}
}
2. 自定义加密选项
// 设置加密算法(默认是 AES-256-CBC)
await execute(db, `PRAGMA cipher = 'aes-256-cfb';`);// 设置加密迭代次数(影响密钥派生)
await execute(db, `PRAGMA kdf_iter = 64000;`);

这些选项可以根据安全需求进行调整,但需要注意不同的设置可能会影响兼容性和性能。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无人机不再“盲飞”!用Python搞定实时目标识别与跟踪

友友们好! 我是Echo_Wish,我的的新专栏《Python进阶》以及《Python!实战!》正式启动啦!这是专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会…

Vue-7-前端框架Vue之应用基础从Vue2语法到Vue3语法的演变

文章目录 1 基于vite创建1.1 对比webpack和vite1.2 创建工程1.3 启动项目2 调试工具Vue.js Devtools3 src结构3.1 index.html3.2 main.ts3.3 App.vue(根组件)4 示例(Vue2的语法)4.1 Person.vue4.2 App.vue4.3 选项式API对比组合式API4.4 程序流程5 示例(Vue3的语法)5.1 setup概…

上线iOSApp前抓包工具协作保障接口行为一致性(iOS抓包)

项目上线前,你是否总会担心“接口是不是在某个边缘条件下表现不一致”?哪怕单元测试通过、接口文档齐全,真到线上用户手上,总还是可能出现一些环境相关的异常。 最近参与某App大版本上线前的质量验证流程,我们特别安排…

Java可变参数:灵活编程的秘密武器

Java可变参数的理解与应用 Java中的可变参数(Varargs)允许方法接受数量不定的同类型参数,简化了方法调用时的参数传递。可变参数通过在参数类型后添加...实现,本质上是一个数组,但在调用时可以传入多个单独的参数。 …

汽车 CDC威胁分析与风险评估

汽车 CDC(连续阻尼控制系统)的威胁分析与风险评估需结合其技术特性、应用场景及行业标准展开。以下是详细解析及实例说明: 一、CDC 系统技术原理与结构 CDC(Continuous Damping Control)通过实时调节悬挂阻尼力提升驾…

TensorFlow 安装与 GPU 驱动兼容(h800)

环境说明TensorFlow 安装与 GPU 驱动兼容CUDA/H800 特殊注意事项PyCharm 和终端环境变量设置方法测试 GPU 是否可用的 Python 脚本 # 使用 TensorFlow 2.13 在 NVIDIA H800 上启用 GPU 加速完整指南在使用 TensorFlow 进行深度学习训练时,充分利用 GPU 能力至关重要…

Laravel 项目中图片上传后无法访问的问题

情况: Laravel 提供了 php artisan storage:link 命令,用于创建符号链接(Symbolic Link),将 storage/app/public 映射到 public/storage。但是上传图片之后 文件目录确实有 但是无法访问。 1. 删除已经创建的 rm -rf…

Tesollo携人形机器人手进军国内市场

Tesollo灵巧手是Tesollo公司研发的一系列机器人灵巧手产品,涵盖两指到五指的设计 产品型号与特点 Delto-5F五指灵巧手:具备20个自由度,每个手指配备4个独立关节,抓握力达到7公斤,每个关节空载可达75转/分钟&#xff0…

Python文件操作的“保险箱”:with语句深度实战指南

目录 一、with语句的底层运作原理 资源获取阶段 资源释放阶段 二、文件操作实战场景解析 场景1:基础文件读写 场景2:异常处理进阶 场景3:复合资源管理 三、自定义上下文管理器 四、with语句的性能考量 五、实战经验总结 在Python编程中,文件操作是日常开发的高频…

openKylin高校沙龙 | 走进成都高校,推动开源技术交流与人才培养

openKylin高校沙龙 | 成都高校 4月25日,CCF开源发展委员会“开源高校行”暨红山开源openKylin高校行成都站圆满举办,这场连接两所大学的开源知识盛会,为成都信息工程大学与电子科技大学的300余名与会师生带来了前沿的行业思考与技术实践。Op…

即梦3.0更新后市面上的的评价如何?

设计师紧握数位板缩在墙角,全息投影中的AI正在生成同风格设计图,地面倒影显示“人类设计师生涯倒计时”。当最新一代AI绘图工具悄然开启测试时,设计圈陷入集体震动——有人惊叹“以后还干XX,都回家卖煎饼吧”,也有人彻…

haproxy搭建nginx网站访问

文章目录 一.案例概述2.1 HTTP请求2.2 负载均衡常用调度算法①RR(Round robin)②LC(least connections)③SH(source hashing) 2.3 常见的web群集调度器3.实验环境 二.实验步骤1.两台web网站步骤相同 安装we…

进程间通信之socketpair

进程间通信之socketpair 源代码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h>int main() {//父子通讯管道int m_pipe[2];//创建管道if(socketpa…

跟着AI学习C# Day29

&#x1f4c5; Day 29&#xff1a;C# 综合进阶知识回顾与职业发展建议 ✅ 学习目标&#xff1a; 回顾 C# 进阶学习路径&#xff1b;总结核心知识点&#xff0c;构建完整的技能体系&#xff1b;理解 C# 高级开发者应具备的核心能力&#xff1b;探索 C# 在不同技术领域的应用场…

茶席布置实训室:传承与创新的茶文化空间

一、茶席布置实训室的重要意义 茶席布置实训室是茶文化传承与创新的重要载体。在现代社会&#xff0c;茶文化的弘扬不仅是对传统的尊重&#xff0c;更是对生活品质和精神境界的追求。茶席布置实训室为人们提供了一个专业、系统地学习和实践茶文化的场所。它将理论知识与实际操…

jar is missing

在父POM中通过dependencyManagement统一管理版本&#xff0c;然后在子模块中省略版本号。

Linux 内核中 TCP 协议栈的输出实现:tcp_output.c 文件解析

在网络通信领域,TCP(传输控制协议)作为核心的传输层协议,确保了数据在网络中的可靠传输。Linux 内核中的 TCP 协议栈实现复杂而高效,其中 net/ipv4/tcp_output.c 文件是整个 TCP 协议栈的关键组成部分,负责处理数据包的发送、重传、连接管理等核心功能。本文将深入解析该…

MySQL分页原理与慢SQL优化实战

分页查询的本质 在Web应用中&#xff0c;分页是处理大量数据的常见需求。MySQL中的分页通常使用LIMIT offset, size语法实现&#xff0c;例如&#xff1a; SELECT * FROM users ORDER BY id LIMIT 10000, 20; 这条语句看似简单&#xff0c;但隐藏着性能陷阱。让我们深入理解…

Taro:跨端开发的终极解决方案

在当今多终端并存的互联网时代&#xff0c;开发者经常面临一个难题&#xff1a;如何高效地为不同平台&#xff08;如微信小程序、H5、React Native 等&#xff09;开发功能一致的应用&#xff1f;传统的开发方式需要针对每个平台单独编写代码&#xff0c;不仅效率低下&#xff…

STM32F103C8T6 学习笔记摘要(三)

第一节 跑马灯实验 1. 了解电路 结构图 说明一下&#xff1a; 那几个LED的引脚线和数码管的是一样的&#xff0c;如果不想让LED亮&#xff0c;就可以把J11的接线帽拔了这里的引脚是PA0-PA7 原理图 说明一下&#xff1a; 当J11接线帽盖上时&#xff0c;VCC3.3_LED就会有一个正…