在开发过程中,本地数据存储的安全性问题常常被忽视,尤其是SQLite数据库的加密保护。如何有效保护敏感数据,避免因文件系统暴露而导致的信息泄露,是每个开发者都需要重视的问题。
本文将带您掌握:
很多开发者认为本地数据库"相对安全",但实际上:
C#// ❌ 错误做法:明文存储敏感数据
var connectionString = "Data Source=customer.db;";
这种做法让数据库文件完全暴露,任何人都可以直接读取!
AES(高级加密标准)是目前最安全的对称加密算法:
首先安装必要的NuGet包:
BashInstall-Package System.Data.SQLite
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace AppSqliteAes
{
public class EncryptionHelper
{
public static (byte[] key, byte[] iv) GenerateKeyAndIV(string password)
{
using (var sha256 = SHA256.Create())
{
byte[] key = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
byte[] iv = new byte[16];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(iv);
}
return (key, iv);
}
}
public static void SaveIVToFile(string filePath, byte[] iv)
{
using (var fs = new FileStream(filePath + ".iv", FileMode.Create))
{
fs.Write(iv, 0, iv.Length);
}
}
public static byte[] LoadIVFromFile(string filePath)
{
using (var fs = new FileStream(filePath + ".iv", FileMode.Open))
{
byte[] iv = new byte[16];
fs.Read(iv, 0, 16);
return iv;
}
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace AppSqliteAes
{
public class DatabaseEncryptor
{
public static void EncryptDatabase(string inputFilePath, string outputFilePath,
byte[] key, byte[] iv)
{
try
{
using (var aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC; // 使用CBC模式增强安全性
aes.Padding = PaddingMode.PKCS7; // 标准填充模式
using (var outputFileStream = new FileStream(outputFilePath, FileMode.Create))
using (var cryptoStream = new CryptoStream(outputFileStream,
aes.CreateEncryptor(),
CryptoStreamMode.Write))
using (var inputFileStream = new FileStream(inputFilePath, FileMode.Open))
{
inputFileStream.CopyTo(cryptoStream);
}
}
// 保存IV用于解密
EncryptionHelper.SaveIVToFile(outputFilePath, iv);
}
catch (Exception ex)
{
throw new InvalidOperationException($"数据库加密失败: {ex.Message}", ex);
}
}
/// <summary>
/// 解密SQLite数据库文件
/// </summary>
public static void DecryptDatabase(string inputFilePath, string outputFilePath,
byte[] key, byte[] iv)
{
try
{
using (var aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (var outputFileStream = new FileStream(outputFilePath, FileMode.Create))
using (var cryptoStream = new CryptoStream(outputFileStream,
aes.CreateDecryptor(),
CryptoStreamMode.Write))
using (var inputFileStream = new FileStream(inputFilePath, FileMode.Open))
{
// 解密数据并写入输出文件
inputFileStream.CopyTo(cryptoStream);
}
}
}
catch (Exception ex)
{
throw new InvalidOperationException($"数据库解密失败: {ex.Message}", ex);
}
}
}
}
C#using System.Text;
namespace AppSqliteAes
{
internal class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
// 配置文件路径
string password = "MySecure@Password123"; // 生产环境请使用更安全的密码管理方式
string originalDbPath = @"customer.db";
string encryptedDbPath = @"customer_encrypted.db";
string decryptedDbPath = @"customer_decrypted.db";
try
{
Console.WriteLine("🔐 开始SQLite数据库加密过程...");
// 生成加密密钥和IV
var (key, iv) = EncryptionHelper.GenerateKeyAndIV(password);
Console.WriteLine($"✅ 密钥生成完成,密钥长度: {key.Length * 8} 位");
// 加密数据库
DatabaseEncryptor.EncryptDatabase(originalDbPath, encryptedDbPath, key, iv);
Console.WriteLine("✅ 数据库加密完成!");
// 验证加密效果:尝试解密
var savedIV = EncryptionHelper.LoadIVFromFile(encryptedDbPath);
DatabaseEncryptor.DecryptDatabase(encryptedDbPath, decryptedDbPath, key, savedIV);
Console.WriteLine("✅ 数据库解密验证成功!");
// 显示文件大小对比
var originalSize = new FileInfo(originalDbPath).Length;
var encryptedSize = new FileInfo(encryptedDbPath).Length;
Console.WriteLine($"📊 原始文件: {originalSize:N0} 字节");
Console.WriteLine($"📊 加密文件: {encryptedSize:N0} 字节");
}
catch (Exception ex)
{
Console.WriteLine($"❌ 操作失败: {ex.Message}");
}
Console.WriteLine("按任意键退出...");
Console.ReadKey();
}
}
}
分块处理大文件
C#public static void EncryptLargeDatabase(string inputPath, string outputPath,
byte[] key, byte[] iv, int bufferSize = 1024 * 1024)
{
using (var aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
using (var input = new FileStream(inputPath, FileMode.Open))
using (var output = new FileStream(outputPath, FileMode.Create))
using (var crypto = new CryptoStream(output, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
var buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
crypto.Write(buffer, 0, bytesRead);
}
}
}
}
异步操作避免UI阻塞
C#public static async Task EncryptDatabaseAsync(string inputPath, string outputPath,
byte[] key, byte[] iv)
{
await Task.Run(() => EncryptDatabase(inputPath, outputPath, key, iv));
}
通过本文的实战指南,您已经掌握了SQLite数据库AES加密的完整解决方案:
💬 互动时间:
觉得这篇文章对您有帮助?请转发给更多需要的C#开发同行,让我们一起构建更安全的软件世界!
🔔 关注我,获取更多C#开发实战技巧和最佳实践!
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!