《密码管理:从设备到云端》
第2章 本地密码存储原理

2. 本地密码存储原理

2.1 本地数据库(SQLite)基础

SQLite 是一款轻量级、无服务器的嵌入式关系数据库引擎,非常适合在本地设备上存储密码库。它不需要独立的数据库进程,数据以单一文件形式保存,便于加密和迁移。

📁 本地密码库文件 (vault.db) SQLite 数据库 表: passwords 字段: id, site, username, encrypted_password, ... 🔒 加密存储 AES-256-GCM 主密码派生密钥 每次读写自动加解密

SQLite 的优势:

  • 零配置 —— 无需安装数据库服务,直接读写文件。
  • 跨平台 —— 桌面、移动设备均可使用同一格式。
  • 事务支持 —— 保证密码写入的原子性和一致性。
  • 加密友好 —— 可对整个数据库文件或特定字段加密。

2.2 加密存储(AES-256)概念

AES-256 是当前最主流的对称加密算法,密钥长度256位,被全球政府及金融机构广泛采用。在密码管理器中,所有保存的密码都使用 AES-256 加密后写入 SQLite 数据库。

🔑 AES-256 加密流程 明文密码 "MyP@ssw0rd!" AES-256 密钥 (256位) 密文 a3f8b2... (不可读) 同一密钥加密 & 解密,速度极快且安全 加盐 + 迭代派生,抵抗暴力破解

AES-256 核心特性:

特性说明
密钥长度256 位 (32字节),暴力破解需 2²⁵⁶ 次尝试
加密模式通常使用 GCM (Galois/Counter Mode) 提供认证加密
加盐与迭代结合 PBKDF2 / Argon2 派生密钥,防止彩虹表攻击

2.3 主密码的作用

主密码是密码管理器的“万能钥匙”。它不直接用于加密数据库,而是通过密钥派生函数 (KDF) 生成 AES-256 加密密钥。主密码的强度直接决定整个密码库的安全等级。

🧩 主密码 → 加密密钥 派生流程 主密码 用户输入 KDF 派生 PBKDF2 / Argon2 + 随机盐 + 迭代 AES-256 密钥 用于加解密数据库 主密码不存储,只存储盐和迭代次数 每次解锁时重新派生密钥,内存中临时使用 主密码丢失 = 所有密码永久丢失(无法恢复)

主密码安全准则:

  • 长度优先 —— 至少12个字符,推荐16+。
  • 避免常见模式 —— 不要使用生日、单词、键盘序列。
  • 唯一性 —— 主密码绝不用于其他任何网站或服务。
  • 记忆与备份 —— 建议使用物理密码本或离线密码管理器保管。

📐 本地密码存储架构总览

🔐 本地密码存储架构 👤 主密码 密钥派生 PBKDF2 + 盐 AES-256 加解密引擎 🗄️ SQLite 读写流程 写入: 明文 → AES-256加密 → 存入SQLite 读取: SQLite → AES-256解密 → 明文展示 所有操作在内存中完成,数据库文件始终为密文

💻 核心代码示例 (Python + SQLite + AES-256)

import sqlite3
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os, hashlib

# 1. 派生密钥 (主密码 + 盐)
master_pwd = b"MyStrongMasterP@ss!"
salt = os.urandom(16)
key = hashlib.pbkdf2_hmac('sha256', master_pwd, salt, 100000, dklen=32)

# 2. 加密密码 (AES-256-GCM)
aesgcm = AESGCM(key)
nonce = os.urandom(12)
plaintext = b"MySecretPassword123"
ciphertext = aesgcm.encrypt(nonce, plaintext, None)

# 3. 存入 SQLite
conn = sqlite3.connect('vault.db')
conn.execute('''CREATE TABLE IF NOT EXISTS passwords
                (id INTEGER PRIMARY KEY, site TEXT, username TEXT,
                 encrypted BLOB, nonce BLOB, salt BLOB)''')
conn.execute('INSERT INTO passwords (site, username, encrypted, nonce, salt) VALUES (?,?,?,?,?)',
             ('example.com', 'alice', ciphertext, nonce, salt))
conn.commit()

# 4. 解密读取
row = conn.execute('SELECT encrypted, nonce, salt FROM passwords WHERE id=1').fetchone()
dec_key = hashlib.pbkdf2_hmac('sha256', master_pwd, row[2], 100000, dklen=32)
aesgcm2 = AESGCM(dec_key)
decrypted = aesgcm2.decrypt(row[1], row[0], None)
print(decrypted.decode())  # MySecretPassword123
conn.close()

✅ 实际产品中会使用更安全的 Argon2 派生,并采用随机盐+迭代,确保每个密码独立加密。

专注课程资料整理