Yii框架的国密算法怎么集成_使用openssl扩展实现SM2/SM4【速查】

看不見的法師

看不見的法師

2026-04-08

765人浏览

原创

sm2密钥生成须用国密版openssl并配置sm2p256v1曲线;sm4加解密需openssl_cipher_sm4_cbc及严格16字节iv;yii需自定义加密组件,且底层依赖gmssl动态库支持。

yii框架的国密算法怎么集成_使用openssl扩展实现sm2/sm4【速查】

SM2密钥生成必须用openssl_pkey_new()配国密配置

OpenSSL原生不支持SM2,得靠国密版OpenSSL(如GMSSL)编译时启用enable-sm2,PHP的openssl扩展才能识别sm2算法名。直接调openssl_pkey_new()默认走RSA,不加配置会静默失败或生成RSA密钥。

  • 生成前必须用openssl_conf_read_file()加载含sm2支持的openssl.cnf,或在openssl_pkey_new()参数中显式传入['curve_name' => 'sm2p256v1']
  • 私钥导出要用openssl_pkey_export(),不能用openssl_pkey_get_private()get_resource_id()——后者返回的是资源句柄,不是PEM字符串
  • Yii里存私钥别用yii\helpers\BaseStringHelper::base64Encode()二次编码,SM2私钥PEM本身已含Base64,重复编码会导致解密失败

SM4加解密必须指定OPENSSL_CIPHER_SM4_CBC且IV长度严格16字节

PHP 8.1+才内置OPENSSL_CIPHER_SM4_CBC常量,低版本需手动定义为0x80001。SM4的CBC模式对IV要求比AES更硬性:必须恰好16字节,且不能复用——哪怕只差1字节,openssl_encrypt()也会返回false,错误信息是"iv length is incorrect"

Yii Framework 2.0.51
Yii Framework 2.0.51

下载 Yii Framework 2.0.51 官方 Basic 应用模板,查看 Composer 安装方式、版本信息与开发文档。

下载
  • 生成IV务必用random_bytes(16),别用mt_rand()拼接,后者输出非二进制安全
  • 加密后数据需和IV一起存储,推荐格式:base64_encode($iv . $ciphertext),解密时substr($data, 0, 16)取IV,substr($data, 16)取密文
  • Yii的yii\security\CipherTool不识别SM4,别试图塞'cipher' => 'sm4-cbc'进去,会报"Unsupported cipher"

Yii中替换默认加密组件要重写encryptByKey()decryptByKey()

Yii的yii\security\CryptHelper底层调openssl_encrypt(),但硬编码了AES-128-CBC,没法通过配置切SM4。必须继承并重写两个方法,且注意密钥处理逻辑——SM2签名验签用的是椭圆曲线密钥对,而SM4加解密用的是对称密钥,二者密钥格式、长度、用途完全不兼容。

  • SM4对称密钥必须是16/24/32字节,用hash_hmac('sm3', $password, $salt, true)派生比直接md5()更合规
  • SM2签名时,私钥用于openssl_sign(),但需指定OPENSSL_ALGO_SHA256而非OPENSSL_ALGO_SM3——国密版OpenSSL实际把SM3哈希内嵌在签名流程里,PHP层看不到单独的SM3算法标识
  • 别在config/web.php里全局替换'crypt' => ['class' => MySm4Crypt::class],Yii的密码哈希(如Yii::$app->security->generatePasswordHash())仍走bcrypt,和SM4无关

调试时openssl_error_string()返回空?先检查extension=openssl是否加载正确

国密算法报错经常不抛异常,openssl_encrypt()直接返回falseopenssl_error_string()却没内容。这不是代码问题,大概率是PHP没连上国密版OpenSSL动态库。

  • 运行php -i | grep openssl,确认OpenSSL Library VersionGMSSL字样,不是OpenSSL 1.1.1这类标准版
  • Linux下检查ldd $(php-config --extension-dir)/openssl.so | grep ssl,输出应指向libssl.so.1.1-gm之类带-gm后缀的库
  • Windows用户别用PHP官方二进制包,必须用GMSSL官网提供的PHP集成包,否则OPENSSL_CIPHER_SM4_CBC常量根本不存在
事情说清了就结束。国密集成最耗时间的从来不是写代码,而是确认OpenSSL底层到底支不支持、支持到什么程度——函数能调通不代表算法真在跑。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

3264

49

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1151

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

1190

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

3264

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

2144

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

3522

16

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2024.04.29

3936

11

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.07.29

2225

17

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.07

1823

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Yii Framework 2.0 API 官方文档
Yii Framework 2.0 API 官方文档

共0课时 | 0人学习

Yii2.0框架开发实战视频教程
Yii2.0框架开发实战视频教程

共22课时 | 9.1万人学习