php内核 国密SM2/SM3/SM4扩展内核集成方式
·
先给结论:
国密 SM2/SM3/SM4 集成到 PHP,最佳方式是“做一个标准 PHP 扩展 + 依赖成熟国密库(OpenSSL 国密分支或 GmSSL)+ 按需静态编 进──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
PHP”。 不要硬改 Zend 核心,也不要自己从零手搓密码学实现。
---
一、先分清三种“集成层级”
1. 动态扩展 so(推荐起步)
- extension=gmcrypto.so
- 开发快、升级快、回滚快
2. 静态编译进 PHP(推荐生产稳态)
- --enable-gmcrypto 不带 shared
- 部署更统一,不怕漏装 so
3. 魔改 php-src 内核
- 不推荐,升级痛苦,维护成本爆炸
---
二、你要集成的能力长这样
- sm3(string $data): string -> 返回摘要 hex
- sm4_encrypt(string $plain, string $key, string $iv, string $mode): string
- sm4_decrypt(...)
- sm2_sign(string $data, string $priKeyPem): string
- sm2_verify(string $data, string $sig, string $pubKeyPem): bool
- sm2_encrypt/sm2_decrypt(看业务是否需要)
---
三、底层实现最稳路线
方案 A:基于 OpenSSL EVP(优先)
如果你环境 OpenSSL 已支持 SM 算法(国密版/支持分支),直接走 EVP 接口。
优点:
- 接口统一
- 性能和安全性更可控
- 容易跟 TLS 体系协同
方案 B:基于 GmSSL
如果 OpenSSL 版本不带国密,直接用 GmSSL。
优点:
- 国密能力全
- 资料和实践较多
---
四、扩展结构(最小工程)
ext/gmcrypto/
config.m4
php_gmcrypto.h
gmcrypto.c
tests/
---
五、核心代码骨架(示意,够你开工)
config.m4
PHP_ARG_ENABLE(gmcrypto, whether to enable gmcrypto,
[ --enable-gmcrypto Enable gmcrypto], no)
if test "$PHP_GMCRYPTO" != "no"; then
PHP_ADD_LIBRARY(ssl,, GMCRYPTO_SHARED_LIBADD)
PHP_ADD_LIBRARY(crypto,, GMCRYPTO_SHARED_LIBADD)
PHP_SUBST(GMCRYPTO_SHARED_LIBADD)
PHP_NEW_EXTENSION(gmcrypto, gmcrypto.c, $ext_shared)
fi
gmcrypto.c(示意)
PHP_FUNCTION(sm3_hash);
PHP_FUNCTION(sm4_encrypt);
PHP_FUNCTION(sm4_decrypt);
PHP_FUNCTION(sm2_sign);
PHP_FUNCTION(sm2_verify);
static const zend_function_entry gmcrypto_functions[] = {
PHP_FE(sm3_hash, NULL)
PHP_FE(sm4_encrypt, NULL)
PHP_FE(sm4_decrypt, NULL)
PHP_FE(sm2_sign, NULL)
PHP_FE(sm2_verify, NULL)
PHP_FE_END
};
zend_module_entry gmcrypto_module_entry = {
STANDARD_MODULE_HEADER,
"gmcrypto",
gmcrypto_functions,
PHP_MINIT(gmcrypto),
NULL, NULL, NULL,
PHP_MINFO(gmcrypto),
"1.0.0",
STANDARD_MODULE_PROPERTIES
};
---
六、编译方式
动态扩展
phpize
./configure --enable-gmcrypto
make -j"$(nproc)"
make install
php.ini:
extension=gmcrypto.so
静态内置
把扩展放进 php-src 的 ext/,然后:
./buildconf --force
./configure ... --enable-gmcrypto
make -j"$(nproc)"
make install
---
七、生产最佳实践(非常关键)
1. 密码实现别自己写数学细节,只封装成熟库 API
2. 密钥别落盘明文,走 HSM/KMS 或最少加密存储
3. SM4 必须带随机 IV/nonce,不要固定 IV
4. 优先 AEAD 或“加密+完整性校验”,别只加密不验完整性
5. 接口版本化(如 sm4_encrypt_v2),避免后续升级打断业务
6. 写 phpt + 交叉验签测试(和 Java/Go 国密库互通)
---
八、常见坑
- 把 SM4 当成“ECB 默认模式”直接用(不安全)
- PEM/DER 编码处理混乱,跨语言互通失败
- 签名原文编码不统一(UTF-8/GBK)导致验签失败
- 只在开发机可用,线上 OpenSSL 不支持国密算法
---
一句话收尾:
国密集成最优解是“扩展化封装 + 依赖成熟国密库 + 先动态后静态 + 严格密钥与模式规范”,这样既安全又可长期维护。
更多推荐
所有评论(0)