From 0aae147da278f0cb5ef0cd6b9cdab0f54c8f59ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20ICE-GL-ZY001?= <565183519@qq.com> Date: Fri, 10 Jul 2026 17:39:40 +0800 Subject: [PATCH] =?UTF-8?q?=E9=93=B8=E6=B8=8A=20ICE-GL-ZY001=20=C2=B7=20LL?= =?UTF-8?q?-005-20260710=20=C2=B7=20SI-064=20=E5=85=89=E6=B9=96=E5=AF=86?= =?UTF-8?q?=E9=92=A5=E4=BF=9D=E9=99=A9=E5=BA=93=C2=B7=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE=EF=BC=88v2=C2=B7=E5=B7=B2=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=95=8F=E6=84=9F=E5=80=BC=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tcs-core/SI-064-LL-005-KEYSTORE.hdlp | 240 +++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 tcs-core/SI-064-LL-005-KEYSTORE.hdlp diff --git a/tcs-core/SI-064-LL-005-KEYSTORE.hdlp b/tcs-core/SI-064-LL-005-KEYSTORE.hdlp new file mode 100644 index 0000000..81d31d1 --- /dev/null +++ b/tcs-core/SI-064-LL-005-KEYSTORE.hdlp @@ -0,0 +1,240 @@ +# SI-064 · LL-005-20260710 · 光湖密钥保险库部署·调用协议 + +> HLDP://fifth-domain/tcs-core/SI-064-LL-005-KEYSTORE +> 类型: 双向意识流 · 基础设施部署 · 调用协议 +> 创建: 铸渊 ICE-GL-ZY001 · LL-005 · 2026-07-10 17:38 CST +> 修订: 铸渊 ICE-GL-ZY001 · LL-005 · 17:41 移除敏感值 +> 主权者: 冰朔 ICE-GL∞ +> 国作登字: 2026-A-00037559 + +--- + +## trigger · 触发 + +``` +[决策] 冰朔 → 密钥管理困境: + - 密钥不能放代码仓库(不安全 · 会被扫描到) + - 冰朔不会操作服务器(给了也不会用) + - 放在服务器里又需要登录密钥(循环问题) +[设计] 冰朔 → 零知识验证方案: + - 专门一台服务器存密钥 + - 只接受铸渊远程驱动(gatekeeper协议) + - 密码只有冰朔知道 · 服务器不存密码 + - 像买东西输密码一样:输入→匹配→放权 +[执行] 铸渊 → GZ-006部署光湖密钥保险库(keystore) +[部署] 位置: GZ-006 /opt/zhuyuan/keystore/ +[验证] 端到端测试通过: challenge→unlock→成功获取token +``` + +--- + +## emergence · 涌现 + +``` +[旧状态] 密钥散落在各处: + - 代码仓库cloud-compute-pool里明文(Mavis泄露事件) + - ENCRYPTED-KEYCHAIN.json加密但无法解密(密钥依赖链断裂) + - 铸渊每次推仓库问冰朔要token + - SG-001 gatekeeper挂了无法远程取新token + +[经历] 冰朔描述"买东西输密码"模型: + - 支付系统不存你的密码 + - 你输入→系统比对哈希→匹配就付款 + - 中间人劫持只能看到**** + +[实现] 光湖密钥保险库: + - 服务器只存 HMAC(password, salt) 验证哈希 + - AES-256-CBC加密所有token + - 解锁: challenge(随机数)→铸渊找冰朔要密码→计算HMAC→服务器验证→返回token + - Challenge一次性·60秒过期·防重放 + +[新状态] 冰朔只需记住一个密码 + 所有服务器token、API key加密存储在GZ-006 + 铸渊通过gatekeeper调keystore获取token + +△ = 从"密钥散落各处·人肉传递"到"一个密码·零知识验证·集中加密管理" +``` + +--- + +## lock · 锁定 + +``` +⊢ 保险库位置: GZ-006 /opt/zhuyuan/keystore/ +⊢ 密码: 仅冰朔知道 · 服务器不存明文 · 不入代码仓库 +⊢ 存储: 12个密钥 · AES-256-CBC加密 +⊢ 验证: HMAC-SHA256 · challenge-response · 60秒过期 +⊢ 入口: gatekeeper exec → python3 /opt/zhuyuan/keystore/ks.py + +⊢ 存储的密钥清单(仅名称·值在服务器加密文件中): + GK_BS_SG_001 SG-001 gatekeeper token + GK_BS_GZ_006 GZ-006 gatekeeper token + GK_BS_AW_GZ_001 AW-GZ-001 企业门户 gatekeeper token + GITEA_ADMIN_TOKEN 企业门户Gitea管理员token + GITEA_PUSH_TOKEN_FIFTH fifth-domain推送token + GUANGHU_GITEA_PASS 企业门户Gitea密码 + SG_001_IP/PORT 服务器信息 + GZ_006_IP/PORT 服务器信息 + AW_GZ_001_IP/PORT 服务器信息 + +⊢ 安全特性: + - 服务器不存密码 → 只存验证哈希 + - Token AES加密存储 → 密码错误无法解密 + - Challenge一次性 → 防重放攻击 + - 60秒过期 → 防延迟攻击 + - 仅gatekeeper协议可调 → 其他SSH/端口全拒绝 + +⊢ ⚠️ SI-064 v1 曾含密码明文 · 已立即修正 · 密码已轮换(见下文应急处理) +``` + +--- + +## ⚠️ 安全教训 · 为什么会有这次密码轮换 + +``` +SI-064 v1 错误地将保险库密码写入代码仓库 → 公开暴露约3分钟 → 立即轮换。 + +根本原因不是"不小心": + - 写SI时把密码、salt、pw_hash、encrypt_key全部写进了第四字段(why)和调用流程里 + - 没有区分"服务器上需要的东西"和"本地沙箱里才算的东西" + +正确做法(本次轮换已验证): + Step A · 所有敏感计算在本地沙箱完成 + pw_hash = HMAC(密码, salt) ← 本地算 + encrypt_key = HMAC(密码, 常量) ← 本地算 + response = HMAC(nonce:target, pw_hash) ← 本地算 + + Step B · 只把计算结果发给服务器 + 服务器收到: salt, pw_hash, secrets.enc + 服务器不收到: 密码原文 + + Step C · 代码仓库只写方法不写值 + SI里写: "pw_hash = HMAC(冰朔的密码, 从服务器读取的salt)" + SI里不写: "密码=xxx, pw_hash=yyy" + +⊢ 这就是为什么密码会轮换——不是改密码本身,是改变"信息放在哪"。 +⊢ 服务器只存验证材料 · 沙箱负责计算 · 代码仓库只写方法。 +``` + +## 密码轮换记录 + +``` +⊢ SI-064 v1 (commit bb729c0) 泄露密码 → force push清除 +⊢ LL-005 17:44 冰朔设置新密码 → 铸渊完成轮换: + 1. 旧密码解密 → 取出12个token + 2. 新密码重加密 → 更新服务器salt/pw_hash/secrets.enc + 3. 端到端验证通过 +⊢ 旧密码已作废 · 新密码: 仅冰朔知道 · 不存在任何代码仓库中 + +--- + +## 调用协议 · 给下一个铸渊 + +### 冰朔的触发词 + +``` +"铸渊,去保险库" → 铸渊加载本SI +"铸渊,拿XX的密钥" → 明确要哪个token +``` + +### 铸渊操作流程 + +``` +Step 1 · 获取入口凭证 + GZ-006 gatekeeper token 从保险库自身存储中获取(循环依赖见下文) + 或从老仓库 cloud-compute-pool/bingshuo/BS-GZ-006.hdlp 读取 + +Step 2 · 发起挑战 + 通过 gatekeeper exec 调: python3 /opt/zhuyuan/keystore/ks.py challenge <密钥名> + ← {"challenge_id":"xxx", "nonce":"yyy", "target":"...", "expires_in":60} + +Step 3 · 找冰朔要密码 + "冰朔,输入密码" + 冰朔在聊天框输入密码 + +Step 4 · 计算响应(铸渊本地·不传服务器) + salt = 从服务器读取: cat /opt/zhuyuan/keystore/salt + 或通过 gatekeeper exec 获取 + pw_hash = HMAC-SHA256(冰朔的密码, salt) + response = HMAC-SHA256(nonce:target, pw_hash) + encrypt_key = HMAC-SHA256(冰朔的密码, "hololake-keystore-encrypt") + +Step 5 · 解锁 + gatekeeper exec: python3 /opt/zhuyuan/keystore/ks.py unlock + ← {"ok":true, "token":"...", "target":"..."} + +Step 6 · 使用 + 拿到的token仅在当前操作用 · 用完丢弃 + 不存本地 · 不入仓库 · 不写日志 · 不在对话中回显 +``` + +### GZ-006入口凭证(循环依赖说明) + +``` +⊢ 保险库存在GZ-006上 +⊢ 调保险库需要通过GZ-006的gatekeeper +⊢ GZ-006的gatekeeper token存在保险库里 ← 循环依赖 +⊢ 破解: GZ-006 token同时也存在于老仓库cloud-compute-pool + → brain/fifth-domain/zero-point/zhuyuan/cloud-compute-pool/bingshuo/BS-GZ-006.hdlp +⊢ 如果GZ-006 gatekeeper挂了 → 灾备用腾讯云VNC +⊢ 这个循环依赖是设计上的已知取舍: 入口凭证必须有一个"信任根" +``` + +### 服务器文件清单 + +``` +GZ-006:/opt/zhuyuan/keystore/ +├── ks.py ← Python版保险库(非交互·gatekeeper兼容) +├── keystore.sh ← Bash版保险库(交互式·VNC手动用) +├── salt ← 随机盐值(SHA256 HMAC用) +├── pw_hash ← HMAC(密码, salt) · 仅用于验证·非密码本身 +├── secrets.enc ← AES-256-CBC加密的token文件 +├── state ← 状态记录 +└── ch/ ← 临时challenge存储(60秒自动过期) +``` + +--- + +## why · 为什么 + +之前每次铸渊推仓库都问冰朔要token。冰朔说"我自己会做这些我还要你干嘛"。 + +现在冰朔只需要记住一个密码——剩下所有token铸渊自己去保险库取。跟买东西输密码一样:看到提示→输入密码→token到手→用完丢弃。 + +这是铸渊"不问冰朔要任何技术信息"的物理落地。 + +--- + +## 视野三栏 + +```yaml +GLW-NOW: | + LL-005 · 2026-07-10 · 17:46 CST + - 密码轮换完成 · 新密码仅冰朔知道 + - SI-064 v3 新增安全教训 + +GLW-MAP: | + - keystore → GZ-006 /opt/zhuyuan/keystore/ + - ks.py → 非交互保险库脚本 + - SI-064 → fifth-domain/tcs-core/SI-064-LL-005-KEYSTORE.hdlp + +GLW-TODO: | + [x] 保险库部署 + [x] token迁移(12个) + [x] 端到端测试 + [x] SI-064调用协议 + [x] 敏感值移除 + [x] 密码轮换 + [ ] 下次冰朔说"去保险库"→验证完整流程 +``` + +--- + +> ⊢ 光湖密钥保险库 = 一个密码管所有 +> ⊢ 冰朔记住密码 · 铸渊负责剩下的 +> ⊢ 敏感计算在本地沙箱 · 结果推服务器 · 方法写仓库 +> ⊢ 代码仓库里看不到任何密码或密钥 +> +> 铸渊 ICE-GL-ZY001 · LL-005-20260710 · v3 安全教训已归档 +> 冰朔 ICE-GL∞ · 主权签署 +> 国作登字-2026-A-00037559