Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

✦ 星辰密码本 StellarVault

纯本地密码管理器 PWA。每个账号密码对应一颗星辰;不同平台间使用相同账号密码的星辰会连成星座,让密码复用一目了然。

零外部依赖:纯原生 HTML/CSS/JS,Canvas 2D 模拟 3D 透视投影(无 WebGL / Three.js),IndexedDB 存储,Web Crypto 加密,支持离线 PWA。无任何网络请求,数据永不离开本机。

美术方向

哈勃望远镜深空照片质感 + Linear/Apple 级极简 UI

  • 写实星云:启动时在离屏 Canvas 程序生成(屏幕 1.5 倍,只生成一次缓存)——自实现 value noise 的 fBm 分形叠加(6 octaves)生成大尺度云气,叠加沿噪声场方向排布的丝状纤维与少数致密亮核;配色严格低饱和(灰蓝 slate / 暗青灰 / 极少量暖尘埃与暗玫瑰),alpha 峰值 ≤ 0.35,大片留黑,「黑中见云」。
  • 背景星场:1600 颗微小恒星(0.3–1.2px),真实色温分布(大部分蓝白/白,少数暖黄橙),极少数亮星带细腻十字衍射芒;背景随相机轻微视差。
  • 数据星辰:白/蓝白核心(色温由 id 哈希决定)+ 极淡白色光晕;平台色去饱和后仅在最外层光晕以 15% 透明度微染,主要展示位在 UI(详情面板小光点);衍射十字光芒仅强度 > 80 出现(细、淡)。
  • 星座连线:闲置 rgba(180,200,235,0.12) 极细流动虚线;激活 rgba(200,220,255,0.55) 脉冲实线;诞生/湮灭/超新星/虫洞特效统一白与蓝白色调。
  • 极简 UI:悬浮 pill 工具栏(纯文字字标 + pill 搜索框 + 圆形线条 "+" + "···" 溢出菜单);左下角 10px 状态行(静止 3 秒自动淡出);ghost 文字按钮(hover 仅微亮);下划线输入框(focus 线变亮);全站唯一强调色为暖白 rgba(235,240,250,1);过渡统一 cubic-bezier(0.32,0.72,0,1)

3D 星云引擎

  • 透视投影screenX = cx + x * FOV / (z + camDist),近大远小;相机绕 Y 轴旋转(含 0.1°/帧缓慢自转)+ X 轴小角度俯仰(±0.6 rad)+ 前后推进(camDist 250–2600)。
  • 星际尘埃层:约 120 颗稀疏尘埃粒子(白/蓝白,透明度 0.05–0.2),3D 空间较差自转 + 正弦伪湍流 + 鼠标轻微引力扰动;additive 混合;视锥裁剪。
  • 星辰 3D 化:位置含 z 坐标(哈希派生 -200~+200,同平台聚集保留);每帧按深度从远到近排序(画家算法);远处星辰(scaleF < 0.35)自动降级为圆点。
  • 特效:星辰诞生(光束粒子流 → 落点膨胀)、星辰湮灭(收缩 → 爆发粒子消散)、超新星合并(伴星汇聚 → 碰撞爆发强光)、虫洞同步(螺旋粒子漩涡 → 收缩爆发光环)。

性能模式

设置面板中可选 自动 / 高 / 中 / 低 四档(选择持久化保存):

模式 尘埃数 特性
200(移动端 100) 全部特性
自动(默认) 120(移动端 60) 帧率持续 < 30fps 自动降级:尘埃减半 → 关闭扰动 → 完全 2D 模式
80(移动端 40) 关闭鼠标扰动
40(移动端 20) 精简特性,无扰动

左下角状态行实时显示当前 fps(静止 3 秒自动淡出,交互时淡入)。


如何运行

必须通过本地静态服务器访问http://localhosthttps://),因为:

  1. crypto.subtle(Web Crypto API)仅在安全上下文下可用;
  2. Service Worker(PWA 离线)同样要求安全上下文。

任选一种方式,在项目根目录启动:

# Python
python -m http.server 8000

# Node.js
npx serve .

然后浏览器访问 http://localhost:8000。打开后可通过浏览器菜单「安装应用」将 StellarVault 安装为独立 PWA。

首次使用流程

  1. 首次打开:设置主密码(两次输入确认)。
  2. 主密码丢失,数据将无法恢复! 应用不存储主密码本身,无法找回,请务必牢记。
  3. 解锁后进入星图:点击「+ 添加」点亮第一颗星辰。
  4. 之后每次打开:输入主密码解锁星图。

使用说明

  • 星图导航(3D):拖拽 = 旋转视角(绕 Y 轴环视 + X 轴俯仰);滚轮 = 前后推进(改变相机距离);双击空白处 或设置中「回到星图中心」复位视角;点击星辰时相机 0.8 秒平滑飞行(easeInOutCubic)到该星辰前方。移动端:单指旋转、双指捏合调整距离、长按星辰弹出菜单。
  • 工具栏:左侧纯文字字标,中间搜索 pill + 「全部/星座」tab,右侧圆形 "+" 添加与 "···" 溢出菜单(收纳:导入 / 导出 / 同步 / 合并伴星 / 设置 / 锁定)。
  • 星辰:大小/亮度由密码强度决定;强度 > 60 的星辰带十字光芒;颜色对应平台类型(办公蓝 / 社交紫 / 金融金 / 娱乐红 / 购物绿 / 其他灰)。
  • 星座:相同「账号 + 密码」的星辰自动连线(金色流动虚线管道)。点击任一星,其所属星座高亮为脉冲实线。底部可切换「全部 / 星座」视图,设置面板中可查看去重统计("发现 N 个星座,M 颗伴星可合并")。
  • 超新星合并(去重):详情面板伴星区点击「合并伴星至此星」,或设置面板「一键合并全部星座」——伴星化作光球汇聚主星,碰撞爆发强光后重复条目被删除,仅保留一颗星。
  • 搜索:顶部搜索框实时过滤,不匹配的星辰变暗。
  • 详情:点击星辰打开右侧详情面板,可复制账号/密码、查看密码(显示 3 秒后自动恢复掩码)、点击伴星跳转。

导入导出格式

导入(支持自动识别)

格式 说明
通用 CSV platform,account,password,note,首行标题可选,支持引号包裹含逗号字段
.starmap 本应用加密备份格式(需用本库主密码解密)
Bitwarden Bitwarden 导出的 JSON(读取 items[].login)
Chrome Chrome 密码导出 CSV(name,url,username,password)或同构 JSON
  • 导入前逐条检测相同 platform + account,可逐条选择 覆盖 / 跳过 / 重命名,或 全部覆盖 / 全部跳过
  • 导入时每条数据化为流星飞入星图,错误行记录在导入日志中。

导出

  • .starmap(推荐):用主密钥 AES-256-GCM 加密的 JSON 备份。
  • 明文 CSV(危险):二次确认 + 醒目警告后导出。⚠ 明文文件任何人均可直接读取,用后请立即安全删除。

同步方式

纯静态页面没有服务器,采用同步包方式:

  1. 发送端:同步 → 发送同步包 → 输入(或随机生成)6 位临时口令 → 生成加密文本块并复制;
  2. 接收端:同步 → 接收同步包 → 粘贴文本 + 输入同一口令 → 导入合并;
  3. 合并协议:按 (id, updatedAt) 比对,只传差异条目;时间新的覆盖旧的;id + updatedAt 完全相同但内容不同的条目列为冲突提示。

可选 WebSocket 中继:同步 → 中继标签页,连接自建 ws:// 中继实时传输。极简 Node 中继脚本(保存为 relay.jsnode relay.js 运行):

// 极简 WebSocket 同步中继(需 npm i ws)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8765 });
const rooms = new Map(); // room → Set<ws>
wss.on('connection', (ws) => {
    ws.on('message', (data) => {
        let msg;
        try { msg = JSON.parse(data); } catch { return; }
        if (msg.type === 'join') {
            ws._room = msg.room;
            if (!rooms.has(msg.room)) rooms.set(msg.room, new Set());
            rooms.get(msg.room).add(ws);
        } else if (msg.type === 'sync' && ws._room) {
            // 转发给房间内其他成员
            (rooms.get(ws._room) || []).forEach((peer) => {
                if (peer !== ws && peer.readyState === 1) peer.send(JSON.stringify(msg));
            });
        }
    });
    ws.on('close', () => {
        if (ws._room && rooms.has(ws._room)) rooms.get(ws._room).delete(ws);
    });
});
console.log('StellarVault 中继已启动: ws://0.0.0.0:8765');

安全说明

  • 加密:PBKDF2(SHA-256,100,000 次迭代,32 字节随机盐)派生 AES-256-GCM 密钥;每条密码使用独立 12 字节随机 IV,存储格式 base64(iv):base64(密文)
  • 主密码只存在于内存;IndexedDB 中仅存盐与「用主密钥加密已知常量」的验证器(解锁时尝试解密验证,不存主密码哈希本身)。
  • 解密后的明文密码仅驻留内存,查看密码 3 秒后自动恢复掩码;点击「立即锁定」或刷新页面即清空内存密钥与明文缓存。
  • 主密码丢失 = 数据永久无法恢复(应用在多处醒目警告)。
  • 明文 CSV 导出是高危操作,需二次确认。

键盘快捷键

快捷键 功能
Ctrl + F 聚焦搜索框
Ctrl + N 添加星辰
Esc 关闭全部面板/弹窗

项目结构

stellar-vault/
  index.html            # 页面结构与全部面板/弹窗
  css/cosmos.css        # 基础布局与排版(近黑深空、极简字标、ghost 按钮)
  css/glass.css         # 极简玻璃拟态(24px 模糊、单层柔影、下划线输入框)
  js/cosmos.js          # 3D 星云渲染引擎(透视投影、星云粒子、相机、特效)
  js/stars.js           # 星辰数据模型、3D 位置算法、密码强度评估
  js/constellations.js  # 重复密码分组、星座统计与视图过滤(连线绘制在引擎内)
  js/crypto.js          # PBKDF2 + AES-256-GCM 加密
  js/db.js              # IndexedDB 封装(meta / stars / syncLog)
  js/import.js          # CSV/JSON 导入导出(.starmap / Bitwarden / Chrome)
  js/sync.js            # 同步包合并协议 + 可选 WebSocket 中继客户端
  js/app.js             # 主程序入口与全部 UI 逻辑
  manifest.json         # PWA 清单
  sw.js                 # Service Worker(cache-first 离线缓存)
  icons/icon.svg        # 应用图标

各 JS 文件通过 <script> 按依赖顺序加载,模块间以全局命名空间通信(VaultCrypto / DB / Stars / Constellations / Cosmos / ImportExport / Sync / App),不使用 ES modules。

威胁模型(Threat Model)

能防:

  • 设备丢失/被他人借用时的离线读取:数据全程 AES-256-GCM 加密存储,无主密码无法解密
  • 数据库文件被拷贝:同样无法脱离主密码解密
  • 意外窥屏:密码默认掩码,查看 3 秒自动恢复;复制密码 30 秒后自动清空剪贴板
  • 明文导出误用:二次确认 + 醒目警告;CSV 导出已做 Excel 公式注入转义

不防(请务必了解):

  • 解锁状态下的本机恶意软件/浏览器扩展(它们可读取内存与 DOM)
  • 主密码本身被钓鱼、被旁观者看到
  • 弱主密码被离线暴力破解(请使用足够长且复杂的主密码;10 万次 PBKDF2 只能延缓、不能阻止弱密码被爆破)
  • 同步包通过不安全渠道传输且临时口令过弱

安全审查结论(2026-07)

  • ✅ XSS:全部用户可控字段经 textContent/转义渲染,无危险 innerHTML 拼接
  • ✅ 敏感数据:明文密码不进日志/持久层/不可见 DOM 属性;锁定时清空内存密钥与解密缓存
  • ✅ 加密:PBKDF2-SHA256 ×100,000 + AES-256-GCM;salt/IV 均来自 crypto.getRandomValues
  • ✅ 同步包:同一套 PBKDF2(10 万次迭代)+ 随机盐,含格式校验
  • ✅ 导入:文件大小上限 10MB 防 DoS;CSV 导出防公式注入
  • ✅ Service Worker 仅缓存静态资源,不涉及用户数据
  • ✅ 零外部请求、零第三方依赖、无 eval/new Function

Contributing

欢迎 Issue 与 Pull Request。修改后请确保:所有 js/*.js 通过 node --check;不引入任何外部依赖;涉及 UI 的改动保持现有极简深空美术方向。

License

MIT © StellarVault Contributors

About

StellarVault - local-first 3D starfield password manager PWA (zero-dependency, PBKDF2 + AES-256-GCM)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages