Przeglądaj źródła

add: gmssl,添加SM2密钥生成函数

https://gitee.com/openLuat/LuatOS/issues/ICV08U
Wendal Chen 5 miesięcy temu
rodzic
commit
f3b435c93a

+ 42 - 1
components/gmssl/bind/luat_lib_gmssl.c

@@ -82,7 +82,7 @@ sm2算法加密
 @string 公钥y,必选. HEX字符串
 @string 待计算的数据,必选,最长32字节, 非HEX字符串
 @boolean 输出模式,默认false. false-GMSSL默认格式DER, true-网站兼容模式
-@boolean 标准版本,默认false. false-C1C3C2新国际, true-C1C2C3老国际
+@boolean 标准版本,默认false. false-C1C3C2新国际, true-C1C2C3老国际. 仅"网站兼容模式"时有效
 @return string 加密后的字符串, 原样输出,未经HEX转换. 若加密失败会返回nil或空字符串
 @usage
 -- 提示 mode/mode2 参数是 2023.10.17 新增
@@ -674,6 +674,46 @@ static int l_sm2_verify(lua_State *L)
     return 1;
 }
 
+/*
+SM2密钥生成
+@api sm.sm2keygen()
+@return string 公钥X, HEX字符串
+@return string 公钥Y, HEX字符串
+@return string 私钥, HEX字符串
+@usage
+-- 本函数于2025.8.27新增
+-- 注意返回值是HEX字符串, 传递给sm2系列函数可以直接使用
+-- 如果传递给服务器, 按格式需要, 可能需要 fromHex 操作
+local pkx, pky, private = gmssl.sm2keygen()
+local originStr = "32wrniosadnfvnadsio;fasiow"
+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
+
+-- 提醒, 生成的密钥对请妥善保管
+-- 一定要看 gmssl.sm2encrypt 的文档和demo
+*/
+static int l_sm2_keygen(lua_State *L)
+{
+    int ret = 0;
+    SM2_SIGN_CTX ctx = {0};
+    ret = sm2_key_generate(&ctx.key);
+    if (ret != 1) {
+        LLOGW("sm2_keygen %d", ret);
+        return 0;
+    }
+    char tmp[128] = {0};
+    luat_str_tohex((const char*)ctx.key.public_key.x, 32, tmp);
+    lua_pushlstring(L, tmp, 64);
+    luat_str_tohex((const char*)ctx.key.public_key.y, 32, tmp);
+    lua_pushlstring(L, tmp, 64);
+    luat_str_tohex((const char*)ctx.key.private_key, 32, tmp);
+    lua_pushlstring(L, tmp, 64);
+    return 3;
+}
+
 #include "rotable2.h"
 static const rotable_Reg_t reg_gmssl[] =
 {
@@ -686,6 +726,7 @@ static const rotable_Reg_t reg_gmssl[] =
     { "sm4decrypt",      ROREG_FUNC(l_sm4_decrypt)},
     { "sm2sign",         ROREG_FUNC(l_sm2_sign)},
     { "sm2verify",       ROREG_FUNC(l_sm2_verify)},
+    { "sm2keygen",       ROREG_FUNC(l_sm2_keygen)},
 
 	{ NULL,             ROREG_INT(0) }
 };

+ 10 - 123
luat/demo/gmssl/main.lua

@@ -5,131 +5,18 @@ VERSION = "1.0.0"
 
 log.info("main", PROJECT, VERSION)
 
--- sys库是标配
-_G.sys = require("sys")
-
-if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
-end
-
--- Air101/Air103默认80M主频, 跑国密算法会很慢的,调整到240M
-if mcu and (rtos.bsp() == "AIR101" or rtos.bsp() == "AIR103" or rtos.bsp() == "AIR601" ) then
-    mcu.setClk(240)
-end
 
 sys.taskInit(function()
-
-    sys.wait(1000)
-    log.info("gmssl", "start")
-    -- 未加密字符串
-    local originStr = "!!from LuatOS!!"
-
-    -- SM2 , 非对称加密, 类似于RSA,但属于椭圆算法
-    -- 就当前实现还是比较慢的
-    if gmssl.sm2encrypt then -- 部分BSP不支持
-        local pkx = "ABE87C924B7ECFDEA1748A06E89003C9F7F4DC5C3563873CE2CAE46F66DE8141"
-        local pky = "9514733D38CC026F2452A6A3A3A4DA0C28F864AFA5FE2C45E0EB6B761FBB5286"
-        local private = "129EDC282CD2E9C1144C2E7315F926D772BC96600D2771E8BE02060313FE00D5"
-
-        -- 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
-
-    -- SM3 算法, hash类
-    if gmssl.sm3update then
-        log.info("=== SM3测试")
-        encodeStr = gmssl.sm3update("lqlq666lqlq946")
-        log.info("gmssl.sm3update",string.toHex(encodeStr))
-    end
-
-    if gmssl.sm4encrypt then
-        log.info("=== SM4测试")
-        local passwd = "1234567890123456"
-        local iv = "1234567890666666"
-        -- SM4 算法, 对称加密
-        originStr = ">>SM4 ECB ZeroPadding test<<"
-        --加密模式:ECB;填充方式:ZeroPadding;密钥:1234567890123456;密钥长度:128 bit
-        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;密钥长度:128 bit
-        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;密钥长度:128 bit;偏移量: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
-
-    -- 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
-
+    -- 测试sm2算法, 含密钥生成
+    require "sm2test"
+    -- 测试sm3算法
+    require "sm3test"
+    -- 测试sm4算法
+    require "sm4test"
+    -- 测试sm2签名和验签
+    require "sm2sign"
+
+    log.info("=====================================")
     log.info("gmssl", "ALL Done")
 end)
 

+ 28 - 0
luat/demo/gmssl/sm2sign.lua

@@ -0,0 +1,28 @@
+
+sys.taskInit(function()
+
+    -- 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)

+ 55 - 0
luat/demo/gmssl/sm2test.lua

@@ -0,0 +1,55 @@
+
+function sm2test(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
+
+sys.taskInit(function()
+    -- 未加密字符串
+    local originStr = "!!from LuatOS!!"
+
+    -- SM2 , 非对称加密, 类似于RSA,但属于椭圆算法
+    -- 就当前实现还是比较慢的
+    if gmssl.sm2encrypt then -- 部分BSP不支持
+        local pkx = "ABE87C924B7ECFDEA1748A06E89003C9F7F4DC5C3563873CE2CAE46F66DE8141"
+        local pky = "9514733D38CC026F2452A6A3A3A4DA0C28F864AFA5FE2C45E0EB6B761FBB5286"
+        local private = "129EDC282CD2E9C1144C2E7315F926D772BC96600D2771E8BE02060313FE00D5"
+        sm2test(originStr, pkx, pky, private)
+    end
+
+    -- SM密钥生成
+    if gmssl.sm2keygen then
+        log.info("SM2密钥生成测试")
+        originStr = "32wrniosadnfvnadsio;fasiow"
+        local pkx, pky, private = gmssl.sm2keygen()
+        sm2test(originStr, pkx, pky, private)
+    end
+
+end)
+

+ 11 - 0
luat/demo/gmssl/sm3test.lua

@@ -0,0 +1,11 @@
+
+sys.taskInit(function()
+
+    -- SM3 算法, hash类
+    if gmssl.sm3update then
+        log.info("=== SM3测试")
+        encodeStr = gmssl.sm3update("lqlq666lqlq946")
+        log.info("gmssl.sm3update",string.toHex(encodeStr))
+    end
+end)
+

+ 43 - 0
luat/demo/gmssl/sm4test.lua

@@ -0,0 +1,43 @@
+
+sys.taskInit(function()
+
+    if gmssl.sm4encrypt then
+        log.info("=== SM4测试")
+        local passwd = "1234567890123456"
+        local iv = "1234567890666666"
+        -- SM4 算法, 对称加密
+        originStr = ">>SM4 ECB ZeroPadding test<<"
+        --加密模式:ECB;填充方式:ZeroPadding;密钥:1234567890123456;密钥长度:128 bit
+        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;密钥长度:128 bit
+        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;密钥长度:128 bit;偏移量: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.run()
+-- sys.run()之后后面不要加任何语句!!!!!