20 gmssl国密算法
作者:沈园园 | 最后修改:2026-04-14
一、gmssl 介绍
GMSSL 是一个支持国家密码算法(国密算法) 的开源密码工具库,由中国科学院软件研究所等机构开发,兼容国际密码标准的同时,重点实现了我国自主设计的密码算法(SM 系列),广泛用于国内金融、政务、通信等需符合国家密码标准的领域。
1.1 GMSSL 核心功能
GMSSL 提供了与 OpenSSL 类似的功能,但特别强化了国密算法支持,主要包括:
- 国密算法实现(SM2/SM3/SM4 等)
- 证书管理(支持国密标准证书格式)
- 加密 / 解密、签名 / 验签、密钥交换等密码操作
1.2 核心国密算法(SM2/SM3/SM4)详解
1、SM2:椭圆曲线公钥密码算法
- 类型:非对称加密算法(公钥密码算法)
- 作用:替代 RSA、ECC 等国际算法,用于数字签名、密钥交换、公钥加密。
- 特点:
- 基于椭圆曲线密码(ECC),密钥长度 256 位(安全强度相当于 RSA 2048 位)。
- 签名和加密效率优于 RSA,相同安全级别下密钥更短,适合资源受限场景(如嵌入式设备)。
- 采用国家规定的椭圆曲线参数(SM2p256v1),确保算法合规性。
- 应用场景:电子签名(如合同签署)、身份认证、密钥协商(如 VPN 密钥交换)。
2、SM3:密码杂凑算法
- 类型:哈希算法(杂凑函数)
- 作用:替代 SHA-256 等,用于数据完整性校验、数字签名摘要生成。
- 特点:
- 输出固定长度 256 位(32 字节)哈希值。
- 具备强抗碰撞性(难以找到两个不同数据生成相同哈希值)。
- 计算效率与 SHA-256 相当,安全性满足国家密码标准。
- 应用场景:数字签名的摘要计算(与 SM2 配合使用)、数据校验(如文件完整性验证)、区块链交易哈希(部分国产区块链采用)。
3、SM4:分组密码算法
- 类型:对称加密算法
- 作用:替代 AES 等,用于敏感数据加密 / 解密。
- 特点:
- 分组长度 128 位,密钥长度 128 位,加密模式支持 ECB、CBC、GCM 等。
- 加密效率与 AES 相当,适合批量数据加密。
- 算法设计公开,安全性经过严格验证。
- 应用场景:数据库加密、文件加密、VPN 数据传输加密、政务系统敏感信息保护。
二、演示功能概述
演示gmssl国密算法包含SM2算法, 含密钥生成,SM3算法,SM4算法以及SM2签名和验签;
三、准备硬件环境

1、Air780EGH核心板一块
2、TYPE-C USB数据线一根
3、Air780EGH核心板和数据线的硬件接线方式为
- Air780EGH核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
- 核心板正面的 ON/OFF 拨动开关 拨到ON一端;
四、准备软件环境
4.1 软件环境
在开始实践本示例之前,先筹备一下软件环境:
1、烧录工具:Luatools 下载调试工具
2、内核固件:本demo开发测试时使用的固件为Air780EGH V2032 版本固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;
3、脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EHM_Air780EHV_Air780EGH/demo/gmssl
4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件
准备好软件环境之后,接下来查看如何烧录项目文件到Air780EGH核心板,将本篇文章中演示使用的项目文件烧录到780EGH核心板中。
4.2 API 介绍
gmssl 库:https://docs.openluat.com/osapi/core/gmssl/
五、程序结构
miniz/
│── main.lua
│── gmssl_sm2.lua
│── gmssl_sm3.lua
│── gmssl_sm4.lua
│── gmssl_sm2sign.lua
│── readme.md
5.1 文件说明
main.lua:主程序入口文件。gmssl_sm2.lua:SM2算法, 含密钥生成。gmssl_sm3.lua:SM3算法。gmssl_sm4.lua:SM4算法。gmssl_sm2sign.lua:SM2签名和验签。
六、代码详解
6.1 main.lua
主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。
6.2 gmssl_sm2.lua
SM2算法加解密,含密钥生成。
function gmssl_sm2_encrypt_decrypt(originStr, pkx, pky, private)
-- GMSSL默认格式
log.info("==== SM2 默认GMSSL模式")
local encodeStr = gmssl.sm2encrypt(pkx,pky,originStr)
log.info("sm2默认模式", "加密后", encodeStr and string.toHex(encodeStr))
if encodeStr then
log.info("sm2默认模式", "解密后", gmssl.sm2decrypt(private,encodeStr))
end
-- 网站兼容模式 https://i.goto327.top/CryptTools/SM2.aspx
-- 密文格式 C1C3C2, 新国标, 一般是这种
log.info("==== SM2 网站兼容模式")
local encodeStr = gmssl.sm2encrypt(pkx,pky,originStr, true)
log.info("sm2网站兼容模式 C1C3C2", "加密后", encodeStr and string.toHex(encodeStr))
if encodeStr then
log.info("sm2网站兼容模式 C1C3C2", "解密后", gmssl.sm2decrypt(private,encodeStr, true))
else
log.info("解密失败")
end
-- 密文格式 C1C2C3, 老国标, 老的Java库通常支持这种
log.info("==== SM2 网站兼容模式, 但C1C2C3")
local encodeStr = gmssl.sm2encrypt(pkx,pky,originStr, true, true)
log.info("sm2网站兼容模式 C1C2C3", "加密后", encodeStr and string.toHex(encodeStr))
if encodeStr then
log.info("sm2网站兼容模式 C1C2C3", "解密后", gmssl.sm2decrypt(private,encodeStr, true, true))
else
log.info("解密失败")
end
end
local function gmssl_sm2_task_func()
-- 未加密字符串
local originStr = "!!from LuatOS!!"
-- SM2 , 非对称加密, 类似于RSA,但属于椭圆算法
-- 就当前实现还是比较慢的
if gmssl.sm2encrypt then -- 部分BSP不支持
local pkx = "ABE87C924B7ECFDEA1748A06E89003C9F7F4DC5C3563873CE2CAE46F66DE8141"
local pky = "9514733D38CC026F2452A6A3A3A4DA0C28F864AFA5FE2C45E0EB6B761FBB5286"
local private = "129EDC282CD2E9C1144C2E7315F926D772BC96600D2771E8BE02060313FE00D5"
gmssl_sm2_encrypt_decrypt(originStr, pkx, pky, private)
end
-- SM密钥生成
if gmssl.sm2keygen then
log.info("SM2密钥生成测试")
originStr = "32wrniosadnfvnadsio;fasiow"
local pkx, pky, private = gmssl.sm2keygen()
gmssl_sm2_encrypt_decrypt(originStr, pkx, pky, private)
end
end
sys.taskInit(gmssl_sm2_task_func)
6.3 gmssl_sm3.lua
SM3算法,算HASH值。
local function gmssl_sm3_task_func()
-- sm3算法,算HASH值
local encodeStr = gmssl.sm3("lqlq666lqlq946")
log.info("gmssl.sm3",string.toHex(encodeStr))
-- sm3算法,算HASH值,但带HMAC
local encodeStr = gmssl.sm3hmac("lqlq666lqlq946", "123")
log.info("gmssl.sm3hmac",string.toHex(encodeStr))
end
sys.taskInit(gmssl_sm3_task_func)
6.4 gmssl_sm4.lua
SM4算法加解密。
local function gmssl_sm4_task_func()
if gmssl.sm4encrypt then
log.info("=== SM4测试")
local passwd = "1234567890123456"
local iv = "1234567890666666"
-- SM4 算法, 对称加密
originStr = ">>SM4 ECB ZeroPadding test<<"
--加密模式:ECB;填充方式:ZeroPadding;密钥:1234567890123456;
encodeStr = gmssl.sm4encrypt("ECB", "ZERO", originStr, passwd)
log.info("sm4.ecb.zero", "加密后", string.toHex(encodeStr))
log.info("sm4.ecb.zero", "解密后", gmssl.sm4decrypt("ECB","ZERO",encodeStr,passwd))
originStr = ">>SM4 ECB Pkcs5Padding test<<"
--加密模式:ECB;填充方式:Pkcs5Padding;密钥:1234567890123456;
encodeStr = gmssl.sm4encrypt("ECB", "PKCS5", originStr, passwd)
log.info("sm4.ecb.pks5", "加密后", string.toHex(encodeStr))
log.info("sm4.ecb.pks5", "解密后", gmssl.sm4decrypt("ECB","PKCS5",encodeStr,passwd))
originStr = ">>SM4 CBC Pkcs5Padding test<<"
--加密模式:CBC;填充方式:Pkcs5Padding;密钥:1234567890123456;偏移量:1234567890666666
encodeStr = gmssl.sm4encrypt("CBC","PKCS5", originStr, passwd, iv)
log.info("sm4.cbc.pks5", "加密后", string.toHex(encodeStr))
log.info("sm4.cbc.pks5", "解密后", gmssl.sm4decrypt("CBC","PKCS5",encodeStr,passwd, iv))
-- 完全对齐16字节的对比测试
originStr = "1234567890123456"
encodeStr = gmssl.sm4encrypt("ECB","PKCS7",originStr,passwd)
log.info("sm4.ecb.pkcs7", encodeStr:toHex())
encodeStr = gmssl.sm4encrypt("ECB","PKCS5",originStr,passwd)
log.info("sm4.ecb.pkcs5", encodeStr:toHex())
encodeStr = gmssl.sm4encrypt("ECB","ZERO",originStr,passwd)
log.info("sm4.ecb.zero", encodeStr:toHex())
encodeStr = gmssl.sm4encrypt("ECB","NONE",originStr,passwd)
log.info("sm4.ecb.none", encodeStr:toHex())
end
end
sys.taskInit(gmssl_sm4_task_func)
6.5 gmssl_sm2sign.lua
SM2签名和验签。
local function gmssl_sm2sign_task_func()
-- SM2签名和验签
if gmssl.sm2sign then
local originStr = string.fromHex("434477813974bf58f94bcf760833c2b40f77a5fc360485b0b9ed1bd9682edb45")
local pkx = "ABE87C924B7ECFDEA1748A06E89003C9F7F4DC5C3563873CE2CAE46F66DE8141"
local pky = "9514733D38CC026F2452A6A3A3A4DA0C28F864AFA5FE2C45E0EB6B761FBB5286"
local private = "129EDC282CD2E9C1144C2E7315F926D772BC96600D2771E8BE02060313FE00D5"
-- 不带id的情况,即默认id="1234567812345678"
local sig = gmssl.sm2sign(private, originStr, nil)
log.info("sm2sign", sig and sig:toHex())
if sig then
local ret = gmssl.sm2verify(pkx, pky, originStr, nil, sig)
log.info("sm2verify", ret or "false")
end
-- 带id的情况
local id = "1234"
local sig = gmssl.sm2sign(private, originStr, id)
log.info("sm2sign", sig and sig:toHex())
if sig then
local ret = gmssl.sm2verify(pkx, pky, originStr, id, sig)
log.info("sm2verify", ret or "false")
end
end
end
sys.taskInit(gmssl_sm2sign_task_func)
七、运行结果展示
出现类似于下面的日志,就表示运行成功:
[2025-10-29 16:51:55.069][000000000.365] I/user.==== SM2 默认GMSSL模式
[2025-10-29 16:51:55.296][000000000.912] I/user.sm2默认模式 加密后 3078022022F0E9C08C45EC2D456C184541900B2D069790DF554BD37183453306E49A474E022100A7220907D53AF4A580B6AEC7B8EA53FF5E51F5E56A8ACC440C86F58C4E3EB9110420A4FCAE7ECF86059FB63B0F82A502223E8B4C7CAECBE29E72C05A87DF8BA3C08F040F63EE6697093A495733939D4D68070F
[2025-10-29 16:51:55.526][000000001.150] I/user.sm2默认模式 解密后 !!from LuatOS!!
[2025-10-29 16:51:55.530][000000001.151] I/user.==== SM2 网站兼容模式
[2025-10-29 16:51:55.977][000000001.601] I/user.sm2网站兼容模式 C1C3C2 加密后 7CD71EFCD699E81C5A320DD78357788BA4A4E87C02691EB73225B6E8CC3F1A95730359208D2E6A375E49D84321C9BB28F0D7B65BC348DD07A9ADE9C1F38D053CA5B4128EE908F4494DB1867F0C48D00FCFE3F6A9C38CDA696CABAF36E9D120244AAEC7B42200A0A9C8321EDEDC9010
[2025-10-29 16:51:56.177][000000001.800] I/user.sm2网站兼容模式 C1C3C2 解密后 !!from LuatOS!!
[2025-10-29 16:51:56.182][000000001.800] I/user.==== SM2 网站兼容模式, 但C1C2C3
[2025-10-29 16:51:56.589][000000002.228] I/user.sm2网站兼容模式 C1C2C3 加密后 0429D777A89C474D468CBB4BDE604C5D0111EF6FEB9AD180A9A5167657C4CFD09A0CAAF6D3467CE2564C73A666EC4DE2CA2E28F5B2BBFA9FE5B30CCA39D0B453DB60AF6B2B6DC1E7D76F3E9FF048FEACC850B37144EC64840A84A1A81B4ACF4BDB851391ECC9F13974A76464C9F9624C
[2025-10-29 16:51:56.788][000000002.425] I/user.sm2网站兼容模式 C1C2C3 解密后 !!from LuatOS!!
[2025-10-29 16:51:56.794][000000002.425] I/user.SM2密钥生成测试
[2025-10-29 16:51:57.048][000000002.660] I/user.==== SM2 默认GMSSL模式
[2025-10-29 16:51:57.462][000000003.092] I/user.sm2默认模式 加密后 3081820220227403C3A196042379534047850F01BA8EC3603226AF18E0CE65729EBBBDC68C02201D1FBBD3998FDB2757AE55262F1CDD288C6C403766F77F6D7CB9017457E7EE660420B742677896DEDBBEAF55857603EB4C39FA9DFFDAD6E17AFA27FA0D7C7D2F7EF5041A79A2DF1D84C0B449459A4FE6BCC3A494F9F4CC2D00F9A4A7C4FE
[2025-10-29 16:51:57.674][000000003.301] I/user.sm2默认模式 解密后 32wrniosadnfvnadsio;fasiow
[2025-10-29 16:51:57.681][000000003.301] I/user.==== SM2 网站兼容模式
[2025-10-29 16:51:58.092][000000003.717] I/user.sm2网站兼容模式 C1C3C2 加密后 A615127F2C18731AB83CA50CDC386C0F70506EA3BE6B1B1E74E1F417BCFB992AC9B4F91A4233181CD5C419CA21B5AD46BBA7F2E635D4AC317842E8762A19260218921AB2D4C02C8211E2AC28976B61D33E0AB826B2DE223E6E51729B31B02E02E0C73D5822F12FC4618E6E1F7110278CBD273C152B650C75A423
[2025-10-29 16:51:58.306][000000003.927] I/user.sm2网站兼容模式 C1C3C2 解密后 32wrniosadnfvnadsio;fasiow
[2025-10-29 16:51:58.313][000000003.927] I/user.==== SM2 网站兼容模式, 但C1C2C3
[2025-10-29 16:51:58.748][000000004.372] I/user.sm2网站兼容模式 C1C2C3 加密后 045807522541AF430F7D0F3EE27D0718AA33D17E98F04121CC3039A6C7EA5B219751DA6CDC64B805C5BA08E97CFC7546D72BCBF1CD2329F26190A6CF33D76E37B1BFFEDBA05C31D8673F33CFA5925A5EC0DB37A58F74B30020DE25104E47001D02A23C45814230650A1D9961B5BDC69218DF8AEEB9A66266EF175C
[2025-10-29 16:51:58.947][000000004.581] I/user.sm2网站兼容模式 C1C2C3 解密后 32wrniosadnfvnadsio;fasiow
[2025-10-29 16:51:58.962][000000004.588] I/user.gmssl.sm3 E64FD76F4078E51DCA428323D3FADBD5D52723BBF1379184650DA5CE6002B2BF 64
[2025-10-29 16:51:58.964][000000004.588] I/user.gmssl.sm3hmac FBB67FC936777011AA70336F0F0B6305D529A97A87D8ECA8880472CD2C30A721 64
[2025-10-29 16:51:58.966][000000004.595] I/user.=== SM4测试
[2025-10-29 16:51:58.971][000000004.596] I/user.sm4.ecb.zero 加密后 E8DF19897C0BF1FFA50910C5C548F5A4E9E34BED9F5CEE519CFA24C37A290B25 64
[2025-10-29 16:51:58.973][000000004.596] I/user.sm4.ecb.zero 解密后 >>SM4 ECB ZeroPadding test<<
[2025-10-29 16:51:58.975][000000004.597] I/user.sm4.ecb.pks5 加密后 25B3D6AB8C855115C3A8883FE3ADCC6B9004C83B86CE7A45517CA6736DBA4EFE 64
[2025-10-29 16:51:58.976][000000004.598] I/user.sm4.ecb.pks5 解密后 >>SM4 ECB Pkcs5Padding test<<
[2025-10-29 16:51:58.978][000000004.598] I/user.sm4.cbc.pks5 加密后 A11C24BB018C8124FADAFC9B6BF7932C05BA2F24E9DFB9D79D982A676F9C010C 64
[2025-10-29 16:51:58.979][000000004.599] I/user.sm4.cbc.pks5 解密后 >>SM4 CBC Pkcs5Padding test<<
[2025-10-29 16:51:58.981][000000004.600] I/user.sm4.ecb.pkcs7 B083DCC0A9F64BD9FAE2FA8C936E3D776C88F739AF2A29A735381F5677BADEF7 64
[2025-10-29 16:51:58.983][000000004.600] I/user.sm4.ecb.pkcs5 B083DCC0A9F64BD9FAE2FA8C936E3D776C88F739AF2A29A735381F5677BADEF7 64
[2025-10-29 16:51:58.987][000000004.601] I/user.sm4.ecb.zero B083DCC0A9F64BD9FAE2FA8C936E3D77D2D68ED9FE06CB40C9A150AA5917F15F 64
[2025-10-29 16:51:58.988][000000004.601] I/user.sm4.ecb.none B083DCC0A9F64BD9FAE2FA8C936E3D77 32
[2025-10-29 16:51:59.450][000000005.084] I/user.sm2sign 9C2303667887E45ABA016BBACFF1AF2F3ED764CE220A0B0D67CF9206BF48F26AA2797E5478919FB0C6140B89D7DDA33055428A7B3D40F49E0BAD410624D83199
[2025-10-29 16:51:59.864][000000005.496] I/user.sm2verify true
[2025-10-29 16:52:00.357][000000005.982] I/user.sm2sign 756D9F37525A543A6647370C22DD71ADEEFBF86D83CE87A28889EAC9F63F0C5CFF334A2D99B067EA676437EE1DEC86B8A8F109568A7CF3AFE70A8DD09562F7E2
[2025-10-29 16:52:00.782][000000006.411] I/user.sm2verify true
八、总结
通过本文学习,你可以学习到gmssl国密算法(SM2/SM3/SM4)的使用方法。