密码学 36:密钥如何生成、保存、轮换与撤销——KMS、信封加密与恢复
服务将一笔合成订单加密进数据库,后来轮换了保管密钥,旧订单却都打不开。另一服务宣称“已经撤销密钥”,此前被复制出去的旧明文却依然能读。这两种故障都说明密钥生命周期不只是调用一次加密函数:必须明确谁持有哪个密钥、哪里记录它的版本、轮换有没有重包裹历史密钥、灾难后拿什么恢复,以及删除权限不能追回已泄漏的材料。 从数据密钥到封装密钥 信封加密通常用随机数据密钥 DEK 保护内容,再用受管封装密钥 KEK 保护 DEK。数据密文、两层使用的算法和 nonce、KEK 标识、必要的关联数据必须作为一个可解析的记录保存:后来服务才能知道找谁解开、该在哪些订单上下文使用。记录标识是选择钥匙的索引,不是钥匙本身;一个 “kid=old” 字符串不应让应用直接相信该密文的来源或拿另一个 KEK 强行解开。 123456订单明文 ── AES-GCM(DEK, nonceA, AAD=订单ID) ─► 数据密文 + tag │DEK ── AES-GCM(KEK-old, nonceB, AAD=keyID-old) ─► 封装 DEK + tag轮换:...
密码学 37:算法正确为什么仍会失败——随机数复用、侧信道与验证边界
团队使用成熟密码库,单元测试里的签名和加密都验过,却把 AEAD 的同一个 key/nonce 用来加密两份订单;或者在 ECDSA 签名时复用了签名随机标量。这不是“数学算法被破解”,而是调用者破坏了算法要求的输入条件。回想 05 的四类值:密码 salt、AEAD nonce、签名 nonce、业务防重放序号不共享一个“随机数就行”的规则。 复用为何具体危险 ECDSA 对特定消息摘要 z 与随机标量 k 的一种标准算式是 s = k⁻¹(z + r·d) mod n:d 是签名私钥,r 来自同一临时曲线点。如果同一私钥对不同 z 复用相同 k,两份签名用相同的 r,且差值可逆时,攻击者从公开的 (r,s1,z1)、(r,s2,z2) 解出 k=(z1-z2)/(s1-s2) mod n,进而求 d=(s1·k-z1)/r mod n。恢复的是私钥本身,不是“签名可以重播”这么弱的结果。ECDSA 实际实现还要核对曲线、nonce 生成、低 s 变体和消息预处理,不能拿手算的玩具公式替真正的曲线库。 AES-GCM 的安全要求同一个密钥的 nonce 不重用。GCM 使用计数...
密码学 33:BLS 为什么适合聚合投票——账户签名与验证者签名
有人给你一份聚合签名,说“四个验证者一起同意了这个区块”。验签为真就等于区块有足够票数、已经最终确定吗?不行。你至少要知道这四个公钥对应谁、该时刻谁有投票资格和多少权重、他们各自签的哪个消息与域、聚合里实际有哪些成员,再按协议状态判断阈值。聚合解决的是验证和传输大量相关签名的一部分成本,不是共识规则本身。 不要拿交易签名去解释验证者投票 28 的 Ethereum type-2 交易由执行层 EOA 用 secp256k1 授权:确定账户、nonce、链 ID 和交易字节后,执行客户端还需核对余额、费用和执行规则。共识层验证者的 BLS 签名则用于对规定的共识消息(如 attestation 指向的目标)投票,签名字节由其签名根及 domain 等上下文决定。两种签名各有独立的密钥持有人、验证对象与状态来源;拿“交易账户验签通过”推出“验证者已投票”,或反过来,都是换了命题。 12345678执行层:钱包 secp256k1 ─► 有类型交易的签名字节 ─► 账户规则检查共识层:验证者 BLS 私钥 ─► 指定 slot/root/domain 的签名 ...
密码学 38:结课一——解释并验证一次 HTTPS 订单请求
浏览器向 orders.test 提交一笔合成订单:order=demo-001;quantity=1。如果页面展示“TLS 连接安全”,是不是订单就绝不会重复执行,服务器也必然不会篡改履约结果?并不是。结课先把网络通道、请求应用认证和订单业务事实画到同一条链上,逐层设计能失败的验证。所谓“成功”必须能指向一次具体输入、秘密持有人、可核对输出和信任起点。 第一张图:握手的信任边界 客户端已有预期主机名 orders.test 和只交给这个实验客户端的临时 CA。服务端有对应叶证书及其私钥,握手时还协商临时密钥交换材料。证书链签名告诉客户端公钥由指定信任锚所授权的签发关系连接而来;检查 SAN 和用途才把服务端与预期主机名联系起来。TLS 1.3 的 CertificateVerify 以服务器证书对应私钥签握手摘要,Finished 用派生出的握手密钥认证前面的握手内容;证书 CA 签名、服务器握手签名与 Finished 各认证不同对象,不能缩成“服务器拿私钥加密订单”。 12345678客户端:预期服务名 orders.test + 单独传入的测试 CA ├──► ...
密码学 39:结课二——经 HTTPS 提交交易,分别验证通信与账本
钱包用 HTTPS RPC 提交了一笔“支付测试订单”的 Ethereum 交易,RPC 返回哈希,收据显示 status=1。这意味着什么?它不意味着现实商家已经履约;更不意味着仅凭一个 HTTPS 连接,就能信任 RPC 提供的区块头在预期链的共同历史中。本结课真正需要的,是在同一条实际传输路径上把通道身份、签名授权、规则/状态、交易包含、最终性与现实结果逐个分开,并对错身份、重放和错链给出独立失败证据。 一张贯通图:五问各向谁要答案 1234567891011钱包:临时私钥 ──► type-2 签名交易原始字节 │ └─► 签名:授权指定链 ID、nonce、收款账户、金额、费用 └── TLS 1.3 + 临时 CA 验服务名 orders.test ──► 本地 HTTPS /rpc │ ▼ ...
密码学 20:SSH 为什么既有主机密钥,又有登录密钥
连接一台测试服务器,SSH 客户端既要判断“这真是打算连接的那台主机”,又要让服务器判断“这位用户能不能登录”。两种判断都可能用公钥签名,却不意味着两把密钥可以合并:第一道问题由客户端验证服务器,第二道问题由服务器验证用户。如果把 SSH 登录的公钥当成主机身份,网络上的冒充者就能在用户出示登录证据以前让客户端连错服务器。 第一把密钥:连接的是谁 SSH transport 先协商密钥交换算法、主机公钥算法、加密及完整性算法。以 RFC 4253 §8 的 DH 例子说明输入:客户端和服务器各自产生一份不公开的临时指数,交换公有 DH 份额,分别算出相同的 K。这些公有份额不提供身份。服务器还发送公开的主机密钥 K_S,用相应主机私钥对交换摘要 H 签名。 H 不只是“连接上了”这四个字的哈希;例子的输入包含双方版本串、双方算法协商报文、服务器主机公钥、两份交换公有值及共同秘密 K,并按 SSH 字节类型编码。客户端验证签名,也必须从可信途径知道哪把主机公钥属于期望的服务器。本地 pinned known_hosts 是一种来源;主机证书另需明确签发者与适用主机。若首次连接只点“...
密码学 E02:后量子 KEM、ML-KEM、ML-DSA 与混合握手
有人说:“换成后量子算法以后,把 ML-DSA 签名加进握手,就能替代密钥交换。”这是把两件不同操作放在一个盒子里:ML-KEM 用于建立双方一致的秘密,ML-DSA 用于证明特定消息由签名密钥持有者授权。KEM 共享秘密匹配也不会自动认证发送密文的一端;签名验真也不会自动证明自己与另一端共享了对称记录密钥。旧的量子风险解释应具体指出 RSA/ECDH 的困难假设面临哪类威胁,不能因为“后量子”三个字就宣称工程已经抵抗了未来所有攻击。 KEM 的四个输入输出 受信任的接收方发布 ML-KEM 公钥,保留私钥。发送方拿到已正确绑定身份的公钥后执行封装:输入公钥与随机源,输出可发送的密文 cipherText 以及自己的共享秘密 sharedSecret;接收方对同一密文用私钥解封装,得到相同共享秘密。发错私钥或改封装密文时,许多 KEM 采用隐式拒绝:返回不同的秘密而非清晰抛出“认证失败”。随后必须在有身份约束的协议里通过 transcript/Finished 或应用认证发现双方秘密不一致,不能把“函数没有报错”写成“双方已认证”。 ML-DSA 则取私钥与指定消息字节生成签名,...
密码学 E03:Noise 与 WireGuard——握手模式、身份与密钥更新
有人抓到两个使用 Noise Framework 的系统,宣称“它们都是 Noise,握手双方必然相互认证、能抵抗同样的重放和身份泄露”。不一定。Noise 描述多种不同握手模式;什么静态公钥事先已知,什么身份在握手中发送,谁先能确认谁,以及之后的数据包格式,必须按具体模式和应用实现核对。WireGuard 使用相关的密码学构件和 Noise 体系的握手思路,并不是“任何 Noise 模式加一个 UDP socket”就成了 WireGuard。 从 KK 这一种模式推导身份 本章只选 Noise_KK_25519_ChaChaPoly_BLAKE2b:K 表示两端都在握手开始前已获得并信任对方静态公钥;25519 表示临时和静态密钥交换使用的曲线,ChaChaPoly 对规定的握手 payload 做认证加密,BLAKE2b 参与哈希和派生。双方交换临时公钥,混入静态/临时 DH 得出的秘密,随握手消息处理不断更新握手 hash/密钥状态。两条消息之后 split 得到两方向不同的传输 cipher state;客户端的发送状态与服务端的接收状态对应,反向同理。 1234567...
密码学 E04:多签、阈值签名与 MPC——共同控制怎样表达
三个人管理一个测试钱包,约定“任意两人同意才可转账”。业务工程师在 API 上要求两份独立签名;密码学工程师说可以做阈值签名;产品把它写成“使用 MPC”。他们可能分别描述不同层的东西:谁制定参与规则、谁看到多少份链上签名、私钥是否由一个人完整持有、多个参与者如何共同生成一份签名,不能靠一个“2/3”标签替代。多签、门限签名及安全多方计算可组合,彼此不互为定义。 先把 2/3 写成可验证操作 最直观的链上多签或应用策略是三把各自独立私钥对同一份具有域的字节签名;验证端持有三把事先被授权的公钥清单,核对至少两把不同公钥的有效签名,并检查该账户或应用的业务 nonce 已消费。若收到同一把公钥的两份相同签名,仍只有一名授权人。若改收款人或金额却复用旧签名,不能称两人同意了新交易。链上具体验收要遵循锁定脚本或合约规则;Bitcoin 和 Ethereum 的手续费、发布内容与脚本表现会不同。 阈值签名想得到另一种外观:多个持有私钥份额的参与者交互,按完整协议生成一份可由特定公钥核对的签名。数学上公钥聚合、随机数承诺、会话身份、恶意参与者/rogue-key 检查、掉线恢复等都是协议的一...
密码学 E05:SNARK/STARK 与多项式承诺——证明成本和假设从哪里来
技术选型表经常写:“SNARK 证明短、STARK 透明;换成后者就自动有零知识与永久可用数据。”这句话混淆了五个不同问题:约束什么计算、采用什么承诺及安全假设、证明/验证开销、哪些值公开、能否拿到被证明计算所需数据。如果连两边要证明的关系都不一样,比较一个 proof 的字节数没有意义;如果只用论文的性能数字比较自己没有安装过的 STARK 工具,读者就无法复核。 先固定同一关系和成本单位 34 已实际执行的一条受限关系是:私有 secret 的 Poseidon 承诺等于公开 commitment,公开 amount <= limit。这不是完整订单转账电路;在现实系统里还要约束哪些状态变化、签名授权与费用必须单独设计。Groth16 把这条关系编译为约束,随后需要与电路相关的 proving key / verification key,并依赖设置材料;本地实验只有单人临时设置。证明者提供见证,验证者持有正确的验证密钥、公开输入和 proof。验证成功仅在相应设置及电路关系正确的假设下说明这些值匹配;业务关系漏了条件时,密码学证明仍可真实有效。 多项式承诺给证明系统提...













