Skip to content

v1.4.0 — 可选的 v2 子密钥派生、ZUC 批量密钥流、PHPStan 与 i18n 校验

Latest

Choose a tag to compare

@erikwang2013 erikwang2013 released this 25 Sep 15:18
· 3 commits to main since this release

新增:可选的 v2 子密钥派生(修正 HMAC 参数顺序)

派生各算法子密钥与 MAC 密钥时,hash_hmac($algo, $data, $key) 的两个参数写反了 —— 常量用途标签被当作 HMAC 密钥,密钥材料被当作消息。

无实际可利用性:标签是公开常量,秘密仍参与运算,拿不到主密钥就派生不出任何子密钥、也伪造不了 MAC。但语义确实是反的。由于修正会改变全部子密钥与 MAC 密钥,它被做成 opt-in:

$v1 = EncryptionManagerFactory::fromMasterKey($master);                       // 默认,行为逐字节不变
$v2 = EncryptionManagerFactory::fromMasterKey($master, 'aes-256-gcm', 'v2');  // 修正后的参数顺序

new Sm4CbcEncryptor($key16, macDerivation: 'v2');   // 三个用 MAC 的加密器同样可选

迁移方式、v1/v2 互不可读、以及「两种方案密文在线缆上同前缀,迁移期用错方案读与密文被篡改都表现为 MAC 失败」这条运维提示,都写进了 README 的 §8 子密钥派生方案 v1 → v2(含 11 种语言)。

性能:ZUC 端到端 0.3 → 3.55 MB/s

ZucEngine 新增批量 keystream(int $length): string(引擎级 1.58x),加密器改用它后消掉了每 16 字节一次 pack 与字符串重分配 —— 后者才是大头。既有 step()/nextKey()/构造函数一行未动。

诚实的天花板:每个密钥字约 200 条 PHP 虚拟机指令,纯 PHP 的 ZUC 无法接近原生 AES。评审为此按规范独立手写了一份 ZUC-128 交叉验证,覆盖 26 种长度(含 2047/2048/2049 分块边界)× 随机/全零/全一密钥,并与官方向量、公开发表的 16 字向量比对一致。

工程

  • PHPStan level 9 入 CI(phpVersion: 80000,另开一个非矩阵 job),baseline 从 21 条降到 7 条:AbstractRegistry 加 @template/@extends 后,13 条 registry 相关告警全部消除,下游用户现在能从 $registry->get($id) 拿到真实类型而不是 object。
  • scripts/i18n-verify.php:校验 11 种语言与英文镜像的结构对等(标题级数/代码块/表格行/分隔线/图片,正是它抓出「整节缺失」这类盲区)、结构树路径列、链接与图片可达、TOC 锚点、词条键集与 keep 列表;--write-en 一键重生成英文镜像。已用沙箱逐类破坏验证。
  • 11 种语言文档同步新章节,12/12 结构对等。

验证

  • CI 全绿:PHP 8.0 / 8.1 / 8.2 / 8.3 / 8.4 矩阵 + PHPStan & i18n job
  • vendor/bin/phpunit:260 用例 / 4605 断言(本机 9 项因缺 ext-gmp 跳过,CI 上会实际执行)
  • 独立评审对两处密码学改动做了执行级复核:复算 v1 全部子密钥与 MAC 密钥、变异测试确认固化向量真会失败、按规范手写 ZUC-128 交叉验证 —— 未发现缺陷

升级

无破坏性变更;不传新参数时行为与 v1.3.x 完全一致。唯一注意点:若你曾在自己的代码里对注册表返回值调用接口之外的方法,静态分析现在会报错(这正是这次类型化的目的)。