# PasswordVault **Repository Path**: lyDevelop/password-vault ## Basic Information - **Project Name**: PasswordVault - **Description**: Android 本地密码管理应用,所有数据均保存在本机,不同步云端 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-13 - **Last Updated**: 2026-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: Android, React-native ## README # 密匣 Android 本地密码管理应用。界面和交互均为中文,无账号注册、业务网络请求或云端同步。 ## 功能 - 默认打开应用直接进入密码库,也可以在“设置”中开启启动验证,打开时直接弹出系统指纹或锁屏密码验证,不再显示欢迎解锁页;取消后可点击“重试验证”。 - 新增、编辑账号;保存名称、用户名、密码、网站、分类及备注。删除时移入回收站,可在“设置 → 回收站”手动恢复、永久删除或清空,不会自动清理。 - 搜索名称、用户名、网站和分类,收藏常用账号。 - 使用系统安全随机数生成 12–64 位密码,可选择包含特殊符号。 - 详情页与编辑页的密码默认隐藏,显示后 15 秒自动隐藏。 - 复制用户名和密码,标记敏感剪贴板,30 秒后仅清除仍由本应用持有的内容。 - 开启启动验证后,切入后台或解锁满 4 分钟自动锁定;关闭后不要求启动验证。 - 禁用截图和系统备份。 ## 数据保护 Android Keystore 生成不可导出的 256 位 AES 密钥,账号整体使用 AES-GCM 加密,每次生成新 IV,认证数据绑定记录 ID 和格式版本。开启启动验证时,原生模块维护 4 分钟授权会话;SQLite 只保存 ID、版本、密文、IV 和认证标签。关闭启动验证后,应用直接使用本机 Keystore 密钥打开密码库。界面搜索在打开后的内存中完成。 从旧版本升级且已有密码数据时,首次关闭启动验证会先要求输入一次系统锁屏密码,将旧的认证密钥安全迁移到免启动验证密钥;迁移完成后后续启动即可直接进入密码库。请勿在迁移过程中卸载应用或清除应用数据。 不提供明文存储降级,也不会在密钥丢失时静默删除原有数据。卸载、清除应用数据、移除系统锁屏或密钥失效可能使密码永久无法恢复。本版本支持密码加密的离线导入导出,不提供云端恢复,请为重要账号保留独立恢复方式。此项目尚未经过独立安全审计。 ## 开发运行 需要 Node 22.13+(兼容版本见 package.json)、JDK 17、Android SDK Platform 37、Build Tools 37.0.0 和 NDK 27.1.12297006。准备模拟器或 Android 7+ 设备,并设置系统锁屏密码。 启动前请设置 Android 开发环境变量。macOS 示例(按本机路径调整): ```sh export JAVA_HOME=$(/usr/libexec/java_home -v 17) export ANDROID_HOME="$HOME/Library/Android/sdk" export PATH="$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator" adb devices ``` 其中 `JAVA_HOME` 必须指向 JDK 17,`ANDROID_HOME` 必须指向实际 Android SDK 目录;`PATH` 需要包含 `platform-tools` 和 `emulator`,这样项目才能找到 Java、ADB 和模拟器工具。若 `adb devices` 没有显示设备,请先启动模拟器或通过 USB 连接已开启 USB 调试的 Android 手机。 项目提供了两个快捷脚本(macOS / Linux): ```sh # 检查环境、启动 Metro,并安装启动调试版 ./scripts/start.sh # 构建 Release APK ./scripts/build-release.sh # macOS:自动设置 JDK 17 和 Android SDK 环境变量后构建 Release APK ./scripts/build-release-macos.sh ``` 脚本会在缺少 `node_modules` 时自动执行 `npm ci`。启动脚本会保持 Metro 运行,按 `Ctrl+C` 可停止它;打包脚本执行 `assembleRelease`,并打印 APK 的完整路径。未填写 `android/keystore.properties` 时,Release 产物会是 `app-release-unsigned.apk`;配置个人签名后会生成已签名的 `app-release.apk`。 ### 配置个人 Release 签名 如果还没有签名文件,可以使用 JDK 自带的 `keytool` 生成一份个人 keystore。下面的命令把文件保存到项目目录之外,避免误提交到 Git: ```sh mkdir -p "$HOME/.passwordvault/keys" "$JAVA_HOME/bin/keytool" -genkeypair -v \ -keystore "$HOME/.passwordvault/keys/passwordvault-release.jks" \ -alias passwordvault-release \ -keyalg RSA \ -keysize 2048 \ -validity 10000 ``` 执行过程中会要求设置 keystore 密码、key 密码和证书信息。请牢记这些信息;key 密码可以在提示时直接回车,使用与 keystore 相同的密码。生成后可以用下面的命令查看 alias 和证书信息: ```sh "$JAVA_HOME/bin/keytool" -list -v \ -keystore "$HOME/.passwordvault/keys/passwordvault-release.jks" \ -alias passwordvault-release ``` 如果需要生成可以独立安装的 Release APK,请在项目的 `android/keystore.properties` 中填写生成的 keystore 信息。这个文件已加入 Git 忽略,不要提交: ```properties storeFile=/绝对路径/passwordvault-release.jks storePassword=你的keystore密码 keyAlias=你的alias keyPassword=你的key密码 ``` `storeFile` 填 `.jks` 文件的绝对路径,`keyAlias` 填生成证书时使用的 alias。填写后再次运行 `./scripts/build-release.sh`,输出会变为已签名的 `app-release.apk`。请备份 `.jks` 文件和密码;同一个应用后续更新必须继续使用同一份签名。 ### 后续版本更新与本地数据 发布新版本时,Android 会替换应用代码,但会保留本机的密码数据库、启动验证设置和 Keystore 密钥。当前项目没有云端同步;这里的“增量更新”指更新应用本身,不会把手机上已经保存的密码覆盖掉。 每次迭代按下面的步骤操作: 1. 在 `android/app/build.gradle` 中递增 `versionCode`,并按需修改展示给用户的 `versionName`: ```gradle versionCode 2 versionName "1.1" ``` `versionCode` 必须比上一个版本大。Android 使用它判断 APK 是否为更新版本,具体规则见 [Android 版本管理说明](https://developer.android.com/studio/publish/versioning)。 2. 保持 `applicationId "com.passwordvault"` 不变,并继续使用同一份 `.jks`、`keyAlias` 和密码。Android 更新 APK 必须使用原应用的签名密钥,具体规则见 [Android 应用签名说明](https://developer.android.com/studio/publish/app-signing)。 3. 构建新的 Release APK: ```sh ./scripts/build-release.sh ``` 4. 覆盖安装到手机,不要先卸载应用,也不要清除应用数据: ```sh adb install -r android/app/build/outputs/apk/release/app-release.apk ``` 也可以直接点击 APK 安装;系统应显示为“更新应用”。如果更换签名密钥或修改包名,Android 会把它当作另一个应用,原有数据不会自动迁移。 只更新 JavaScript、界面或原生代码时,不需要处理数据库。若以后修改数据库结构,请增加带事务的数据库迁移逻辑,保留现有表和记录,不能通过删除数据库、重置 `user_version` 或清空表来“升级”。如果修改加密密钥或密文格式,也必须先设计兼容旧数据的迁移流程。 本应用不提供多设备云端同步;换机请使用下述离线迁移功能。 ## 离线换机迁移 两台手机均安装包含迁移功能的版本,系统为 Android 8 或以上。 1. 旧手机进入“设置 → 数据导出 / 导入”,设置并确认至少 12 位的迁移密码,点击“导出加密文件”,保存到本机目录。 2. 通过 USB、蓝牙等离线方式,将 `.mivault` 文件复制到新手机。 3. 新手机进入相同页面,选择本机迁移文件,在上方输入原来的迁移密码,点击“解密并预览”,选择保留本机版本或从备份恢复,再确认导入。 4. 确认新手机中的账号、密码、备注和收藏均正确后,再处理旧手机。 迁移密码独立于手机 PIN,文件采用 PBKDF2-HMAC-SHA256(600,000 次、随机 16 字节盐)与 AES-256-GCM 加密;新手机导入后会使用自己的本机密钥重新加密。忘记迁移密码无法恢复文件,请单独妥善保管。格式为版本化二进制头、盐、IV、认证密文,不包含本机 Keystore 密钥。 导入先预览总数、新增数和相同 ID 数量。默认保留本机版本,跳过相同 ID;选择“从备份恢复”可覆盖相同 ID 的密码、备注等全部字段,并保留备份中的更新时间。覆盖前需二次确认,建议先导出当前密码库。备份中没有的本机账号不会删除;同名但 ID 不同的账号会分别保留。文件整体校验和加密完成后才通过事务写入,失败时回滚。当前上限为 16 MB、10,000 条记录。使用 Android 系统文件选择器,仅请求本机文件;无需广泛存储权限。选择文件期间暂不因后台切换锁定,原有 4 分钟会话上限仍然有效。 ## 回收站 删除账号前弹出确认弹窗,确认后账号移入回收站,不再出现在首页、搜索和收藏中。回收站没有过期时间,也不会自动清空。恢复会保留账号 ID、密码、备注、收藏和原更新时间。永久删除与清空需要再次确认,不能在应用中撤销。此前版本已经永久删除的账号不能凭空恢复,需要使用旧备份。 回收站标记与账号内容一起加密保存,安全密钥迁移包含回收站记录。导出备份只包含正常账号,如需备份回收站内容,请先恢复。导入时回收站中相同 ID 也算已有账号:默认跳过,选择覆盖恢复则回到密码库。永久删除本机记录不会删除你以前导出的备份文件。 ## 项目结构 - src/screens:解锁、账号列表、详情、编辑和安全设置。 - src/components:页面布局、卡片、按钮与公共样式。 - src/stores:授权状态和仅驻留内存的账号状态。 - src/repositories:加密后持久化和账号删除。 - src/services:SQLite、原生加密及敏感剪贴板接口。 - android/app/src/main/java/com/passwordvault/VaultModule.kt:系统认证、Keystore、AES-GCM、安全随机数和剪贴板。 验证结果见 VALIDATION.md。