若烹小鲜
秘钥存储器

项目地址
Storage
Storage 是一个使用 SwiftUI 编写的本机数据存储示例应用。项目主体是 Storage/Storage 下的 Swift 代码,用于把用户输入的数据加密后保存到本机,并在输入相同 key 后读取和解密。
根目录下的 encrypt.py 不是应用运行依赖,它只是用于辅助说明和验证 Swift 代码中的加密逻辑。
项目结构
.
├── Storage/
│ ├── Storage.xcodeproj/ # Xcode 工程文件
│ └── Storage/
│ ├── StorageApp.swift # SwiftUI 应用入口
│ ├── ContentView.swift # 主界面、存储、读取、加密和解密逻辑
│ └── Assets.xcassets/ # 应用资源
└── encrypt.py # 加密逻辑辅助说明脚本
Swift 代码说明
StorageApp.swift
StorageApp 是应用入口。它通过 WindowGroup 启动 ContentView,也就是用户看到的主界面。
ContentView.swift
ContentView 是项目的核心文件,负责以下功能:
- 展示“数据存储器”主界面。
- 提供“读取数据”和“存入数据”两种模式。
- 提供“联网存储”按钮,因为存储服务器为个人使用,所以该部分功能摘除。
- 接收用户输入的十六进制 key。
- 在存入模式中,把文本数据加密后保存到本机。
- 在读取模式中,从本机读取加密数据,并使用用户输入的 key 解密。
- 支持从剪贴板粘贴数据,以及复制加密数据或解密结果。
- 通过提示文字反馈读取、保存、复制、解密失败等状态。
基本功能流程
存入数据
- 在首页点击“存入数据”。
- 输入不超过 64 位的十六进制 key。
- 点击“确认”。
- 输入或粘贴需要保存的文本。
- 点击“加密并存入本机”。
- 应用会把加密结果保存到
UserDefaults中,保存 key 为storedEncryptedPayload。
读取数据
- 在首页点击“读取数据”。
- 输入保存数据时使用的同一个 key。
- 点击“确认”。
- 应用会从
UserDefaults读取本机保存的加密数据。 - 解密成功后显示原始文本;如果 key 不匹配或密文格式无效,会显示解密失败信息。
加密功能说明
Swift 代码使用 Apple 的 CryptoKit,具体算法是 AES.GCM。
当前实现的加密规则如下:
- 用户输入的 key 会先去掉首尾空白。
- 如果 key 长度小于 64 位,会在右侧补
0,直到长度为 64 位。 - key 必须是 64 位十六进制字符串,转换后正好是 32 字节,用作 AES-256 的对称密钥。
- nonce 使用 key 的前 12 字节生成。
- 文本会按 UTF-8 转成二进制数据。
- 使用
AES.GCM.seal加密。 - 最终保存的是
nonce + ciphertext + tag组合数据的 Base64 字符串。
解密时,应用会把 Base64 字符串还原为组合数据,并用同一个 key 调用 AES.GCM.open 解密。
encrypt.py 的作用
encrypt.py 使用 Python 的 cryptography 库复刻了 Swift 中的加密流程:
- 同样会把 key 补齐到 64 位十六进制字符串。
- 同样把 key 转为 32 字节 AES-GCM 密钥。
- 同样取 key 的前 12 字节作为 nonce。
- 同样输出
nonce + ciphertext + tag的 Base64 字符串。
因此,它主要用于解释 Swift 加密逻辑,或在命令行中对照 Swift 端的加密结果。它不是 iOS 应用的一部分,应用运行时不会调用这个 Python 脚本。
运行示例:
python3 encrypt.py
如果本机没有安装依赖,需要先安装:
python3 -m pip install cryptography
注意事项
- 当前数据只保存在本机
UserDefaults中,不会上传服务器。 - “联网存储”功能没有加进去。
- 读取数据必须使用存入时相同的 key。
- 如果 key 错误、密文被修改,或本机没有保存数据,应用会给出对应提示。
- 当前 nonce 由 key 固定派生,适合用于学习和演示现有加密流程;如果要用于生产环境,应改为每次加密生成随机 nonce,并随密文一起保存。