Repository navigation
v1.3.0 — SM2 在 PHP 8.0 的修复、SM3/SM4 原生 OpenSSL、CI 与安全策略
修复
SM2 密钥生成在 PHP 8.0 上直接抛异常(未捕获的 ReflectionException)
Sm2EncryptionService::generateKeyPairHex() 通过反射调用 vendor 的私有 pointMultiply()。PHP 8.0 调用非公开方法必须显式 setAccessible(true)(8.1 起才变成 no-op),因此在本库声明支持的最低版本上,密钥生成会抛出一个 try/catch EncryptionException 接不住的 ReflectionException。
之所以一直没被发现:本地 PHP 8.3 不需要 setAccessible,而本机没有 ext-gmp,SM2 用例长期处于 skip 状态 —— 两层掩护叠加。现在补上 setAccessible、vendor 方法存在性检查与反射句柄缓存;私钥采样仍然用 CSPRNG(vendor 公开的 generateKeyPairHex() 内部用非 CSPRNG 的 gmp_random_range,所以不能直接用它)。
性能
| 路径 | 之前 | 现在 |
|---|---|---|
| SM3(1 MiB 摘要) | 0.01 MB/s、峰值内存 490 MB、85 s | 60+ MB/s、4 MB |
| SM4-CBC(1 MiB 加解密往返) | 17.2 MB/s | 24.4 MB/s |
两者都改为优先走 OpenSSL 原生实现(openssl_digest('sm3') / openssl_encrypt('sm4-cbc')),老版本 OpenSSL 不含对应算法时回退 pohoc/crypto-sm 的纯 PHP 实现,输出逐字节一致。
保证历史数据不受影响:SM3 两条路径已逐字节比对(含空串与 55/56/64 字节分组边界);SM4 同 key/IV 下两条路径密文逐字节一致,并新增了一条用旧实现产出的固化密文仍能解出原文的回归用例。
工程
- CI(
.github/workflows/tests.yml):PHP 8.0–8.4 矩阵,启用gmp+sodium让 SM2 与 XChaCha20 用例真正执行,附带 demo 冒烟与全量php -l。这个矩阵存在的意义就是让上面那类「只在最低版本上炸」的问题无处藏身。 SECURITY.md:漏洞私下披露流程、影响范围与不在范围内的情形。composer.json补homepage/authors/support(含 security 报告入口)。
测试
vendor/bin/phpunit —— 239 用例 / 4506 断言全绿;本机 9 项因缺 ext-gmp 跳过(CI 的 8.0–8.4 矩阵会覆盖 SM2 全路径)。
无破坏性变更:载荷格式、类名、方法签名与算法标识均未变,可直接从 1.2.x 升级。