systemslibrarian/DeckBook

GitHub: systemslibrarian/DeckBook

一个基于扑克牌模拟一次性密钥本的密码学教育 PWA,通过交互式可视化和 CTF 挑战教授流密码原理与密钥重用攻击。

Stars: 0 | Forks: 0

# DeckBook [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/systemslibrarian/DeckBook/actions/workflows/ci.yml) [![Lighthouse](https://github.com/systemslibrarian/DeckBook/actions/workflows/lighthouse.yml/badge.svg)](https://github.com/systemslibrarian/DeckBook/actions/workflows/lighthouse.yml) 一个基于卡片的 one-time keybook 演示,用于教学密钥分发、one-time pads、流密码以及密钥重用的危险。 DeckBook 是一款教育性的展览式 Web 应用(Cipher Museum 主题),它模拟了以下核心理念: **牌的顺序就是密钥。线索只告诉你该使用哪个密钥。** **[▶ 体验在线展览](https://systemslibrarian.github.io/DeckBook/)** | 观看密码运行 | 破解重用的密钥 | 参与拦截挑战 | | --- | --- | --- | | ![观看它如何工作:一张卡牌从牌堆中翻出并移动一个字母](https://raw.githubusercontent.com/systemslibrarian/DeckBook/main/docs/screenshots/visualizer.png) | ![密钥重用攻击实验室:crib dragging 恢复明文](https://static.pigsec.cn/wp-content/uploads/repos/cas/65/6561641b6df238451b69ac70048cdf2396b6c0ea36be1745b58837ad914eef1c.png) | ![挑战模式:从密文恢复两条消息](https://raw.githubusercontent.com/systemslibrarian/DeckBook/main/docs/screenshots/challenge.png) | ## 质量 - **无障碍性:** 在初始页面、所有参考面板展开以及挑战模式下,没有违反 WCAG 2.1 A/AA 标准的 axe-core 违规项,并由 CI 强制执行 ([e2e/a11y.spec.ts](e2e/a11y.spec.ts))。支持完整的键盘操作、 屏幕阅读器标签,并在全局提供 `prefers-reduced-motion` 支持。 - **经过测试:** 针对所有纯逻辑的 54 个单元测试 (Vitest),以及 8 个 Playwright 端到端测试(完整的加密→分享→解密往返过程、挑战解题, 以及无障碍审计)。两套测试套件都会在每次通过 CI 推送时运行。 - **精简且离线:** 完全客户端运行,无需后端。生产环境的资源包大小约为 34 KB JS + 6 KB CSS(gzipped 压缩后),并可作为支持离线使用的 PWA 安装。 - **Lighthouse CI:** [lighthouse.yml](.github/workflows/lighthouse.yml) 在每次推送和拉取请求时,针对构建的站点运行 Lighthouse(桌面预设,运行 3 次),对无障碍性进行门控,并报告性能、最佳实践 和 SEO。每次运行都会上传一份公开报告(URL 位于作业日志中)。 ## 灵感 本项目的灵感来源于 Solitaire 等手动加密教学材料,包括: - https://steemit.com/steemiteducation/@shai-hulud/solitaire-encryption-low-tech-high-security-a-how-to ## 免责声明 DeckBook 是一个用于教育演示的工具,并非生产级密码学。 - 不要使用此应用来保护真实的机密。 - 对于真实的安全需求,请使用经过审计的现代密码学工具。 ## 教学内容 - One-time 密钥材料和密钥标识符 - 为什么密钥重用会失败 - 为什么密钥分发很困难 - 手动/物理密钥本的操作风险 - 为什么存在现代密钥交换(包括后量子 KEM 背景) ## 密码工作原理 该密码是对 26 个字母 A–Z 进行的类似 Vigenere 的加/减运算。不同之处 在于其 keystream 来源于一副洗过的扑克牌。 1. **字母转换为数字。** `A = 0, B = 1, …, Z = 25`。空格、数字 和标点符号在加密前会被去除。 2. **卡牌转换为 keystream。** 每张牌都有一个稳定的值 `0..51` (黑桃 A = 0,梅花 K = 51)。每张牌贡献一个 keystream 字母: keystream[i] = deck[i].value mod 26 一个字母对应一张牌,因此一副完整的牌会产生 52 个 keystream 字母, 单副牌的密钥最多只能加密 52 个字母。26 个 字母表中的每个字母都恰好被两个牌面数字击中,因此 keystream 是均匀分布的。 3. **加密通过 mod 26 加法完成,解密通过减法完成。** cipher[i] = ( plain[i] + keystream[i] ) mod 26 plain[i] = ( cipher[i] - keystream[i] + 26 ) mod 26 对于超过 52 个字母的消息,Advanced multi-deck 模式会依次消耗 额外的全新牌组(字母 0–51 使用第一副牌, 52–103 使用第二副,依此类推)。每副牌都只被使用一次。 通信双方必须已经持有相同的私有 DeckBook。只有 index code(如 `LANTERN-42` 这样的公开标签)和密文会通过 公共信道传输。牌的顺序本身就是机密。 ## 功能亮点 ### 交互式学习 - **观看它如何工作** — 一个动画可视化工具,每次运行一张牌的密码运算。 一张牌从牌堆中翻出,变成一个 keystream 数字,并位移 您消息中的一个字母,带有播放/暂停/单步执行/速度控制。 它是一个沙盒,永远不会消耗真实的密钥。 - **实时字母频率直方图** — 当您在 Encrypt 面板中输入时,两个 柱状图会实时更新:您的明文(具有典型英语特征的尖峰图) 与您的密文(平坦图)的对比。“没有偏爱的字母”这一课, 瞬间可见。 - **带有 crib dragging 的密钥重用攻击实验室** — 使用 相同的密钥加密两条消息,然后手动破解它们。输入一个猜测的单词(“crib”),将其沿着 密文的差值滑动,并在猜测正确的位置观察另一条消息是如何泄露出来的。包含按排名的 “最接近英语特征位置”的提示。 攻击过程中绝不输入任何密钥或牌的顺序 — 仅仅是重用就会导致明文泄露。 - **QR / 分享链接传递** — 每条加密的消息都会生成一个 QR 码和 一个仅携带 index code 和密文的深度链接(绝不包含牌的顺序)。 在另一台设备上扫描它;只有当该设备已经持有 匹配的 DeckBook 时,它才能解密。一条穿越真实公共信道的真实消息。 - **可打印的物理牌表** — 打印样式表会将牌的顺序 输出为一张整洁的表格,以便您可以整理出真实的牌组并手动验证某个字母。 ### 打造体验 - **挑战模式 ("Eve's Intercept")** — 一个可分享、可通过深度链接访问的 CTF 风格 谜题。一名操作员对两条消息重用了同一个密钥;您扮演 窃听者,并仅使用 crib dragging 恢复两条消息,带有实时进度 计量条和获胜时的彩带动画。包含从简单到困难的三个谜题;使用 `#play=` 分享特定谜题。 - **故事框架** — 一个正在进行的 Alice → Bob 任务,且有 Eve 在线监听,将 各个步骤、模拟器和挑战结合在一起,构成一个完整的叙事。 - **可安装、支持离线的 PWA** — Web manifest 和 service worker 使 DeckBook 可以安装在手机或博物馆自助终端上,并在没有 网络的情况下完全可用。Open Graph / Twitter 卡片为分享的链接提供了精致的预览。 ### 对于教育工作者 - 一份随时可用的[教学指南](docs/teaching-guide.md)(教学目标、与应用映射的 45-60 分钟定时 课程、讨论问题、评估、 标准关联)以及一份可打印的[学生练习册](docs/worksheet.md)。 - 应用内的**For Educators** 面板和包含所有关键术语的**词汇表**。 ### 引导式、整洁的布局 - **编号步骤流程** — 核心的发送/接收路径被标记为 1-5 (生成 → 选择密钥 → 准备牌组 → 加密 → 解密),并在 hero 区域提供简洁的 概述,因此一目了然就能看懂操作顺序。 - **可折叠的参考部分** — 说明性面板(密码工作原理、安全模型、什么是 DeckBook? 等)默认作为 可通过键盘操作的可折叠面板,保持页面简短;引导式演示 和 presenter 模式会自动展开它们导航到的任何内容。 ### 核心密码和密钥管理 - 使用 `crypto.getRandomValues()` 进行安全的牌组生成(不使用 `Math.random()`) - 使用 Fisher-Yates 洗牌算法结合拒绝采样以实现无偏整数选择 - 带有 0-51 一致映射的 52 张牌组模型 - DeckBook 模式:10 / 100 / 1,000 个密钥 - 人类可读的 index code 和由 SHA-256 派生的指纹 - 带有自上而下清单的接收方设置视图 - A-Z 模运算加密/解密 - 用于长明文的多副牌组消息模式 - Two-Party Simulator (Alice / 公共信道 / Bob) - 已用/未用密钥跟踪和明确的重用警告 - 导入/导出 DeckBook JSON(用于教育模拟) - 浏览器存储中的本地持久化 - 错误模拟面板 - 移动端响应式布局和无障碍改进 ## 技术栈 - Vite - TypeScript - Vanilla CSS - 完全客户端(无后端) ## 本地开发 ### 1. 安装依赖 ``` npm install ``` ### 2. 运行开发服务器 ``` npm run dev ``` ### 3. 构建生产版本 ``` npm run build ``` ### 4. 在本地预览生产构建 ``` npm run preview ``` ## 测试 - **单元测试** 覆盖了纯密码、攻击分析、分享链接 和卡牌界面模块: npm test - **端到端测试** 驱动真实 UI 完整执行 协议 — 生成 DeckBook,加密,跟随分享链接, 并解密回原始明文 — 此外还包括“没有 DeckBook 的设备无法读取消息”的场景以及动画可视化工具: npm run test:e2e 这两套测试套件都会在每次推送和拉取请求时通过 [ci.yml](.github/workflows/ci.yml) 自动运行。 ## GitHub Pages 部署 此仓库包含一个位于 [deploy-pages.yml](.github/workflows/deploy-pages.yml) 的 Pages 工作流。 ### 一次性仓库设置 1. 打开仓库 Settings。 2. 转到 Pages。 3. 将 Source 设置为 GitHub Actions。 ### 发布流程 - 推送到 `main` 分支。 - 工作流会构建应用程序并将 `dist/` 部署到 GitHub Pages。 ## 无障碍与移动端说明 UI 的设计使其能在小屏幕上使用,并支持键盘导航。 - 语义化的部分和清晰的标签 - 基于文本的 USED/UNUSED 状态指示器(不仅仅是颜色区分) - 具有琥珀色点缀的高对比度暗色主题 - 响应式卡片/网格布局 - 触摸友好的控件和紧凑的移动端行为 - 通过 `prefers-reduced-motion` 提供减少动态效果的支持 ## 安全模型(教育性) 该模型仅在满足以下条件时才展示其安全性: 1. 牌的顺序是使用密码学随机性生成的。 2. 双方事先共享相同的私有 DeckBook。 3. 每副牌的密钥只被使用一次。 4. 已使用的密钥永不重用。 5. 牌的顺序绝不通过公开渠道传输。 6. Index code 不会泄露牌的顺序。 7. 谨慎处理人为错误和消息长度限制。 ## 项目结构 - [index.html](index.html) 应用程序外壳 - [src/cipher.ts](src/cipher.ts) 纯密码核心(加密/解密,牌组,洗牌) - [src/analysis.ts](src/analysis.ts) 纯攻击/分析数学逻辑(crib dragging,频率) - [src/share.ts](src/share.ts) 纯分享链接编码/解码(QR payload) - [src/qr.ts](src/qr.ts) QR 图像渲染助手 - [src/visualizer.ts](src/visualizer.ts) 动画“观看它如何工作”面板 - [src/main.ts](src/main.ts) 应用逻辑和 UI 渲染 - [src/styles.css](src/styles.css) 视觉设计和响应式样式 - [src/challenge.ts](src/challenge.ts) "Eve's Intercept" CTF 谜题模块 - [docs/](docs/) 教学指南和学生练习册 - [scripts/generate-icons.mjs](scripts/generate-icons.mjs) PWA/社交图标生成器 - [tests/](tests/) 针对密码、分析、分享、卡牌界面和挑战模块的 Vitest 单元测试 - [e2e/](e2e/) Playwright 端到端冒烟测试 - [vite.config.ts](vite.config.ts) 用于静态部署的 Vite +est 配置 - [playwright.config.ts](playwright.config.ts) Playwright 配置(启动开发服务器) - [ci.yml](.github/workflows/ci.yml) 构建 + 单元测试 + 端到端测试(包含 a11y)工作流 - [lighthouse.yml](.github/workflows/lighthouse.yml) + [lighthouserc.json](lighthouserc.json) Lighthouse CI - [deploy-pages.yml](.github/workflows/deploy-pages.yml) GitHub Pages 部署工作流 ## 许可证 MIT
标签:PWA, 一次性密码本, 安全教育, 密码学, 手动系统调用, 流密码, 特征检测, 自动化攻击