Browse Source

update: 更新crypto demo

shenyuanyuan 5 months ago
parent
commit
28f5ec6b0f

+ 282 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/crypto/crypto_app.lua

@@ -0,0 +1,282 @@
+--[[
+@module  crypto_app
+@summary crypto_app应用功能模块 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本文件为crypto_app应用功能模块,核心业务逻辑为:
+1、演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+本文件没有对外接口,直接在main.lua中require "crypto_app"就可以加载运行;
+]]
+
+--加密运算主函数
+local function crypto_task_func()
+
+    -- MD5/哈希MD5,输出结果已经hex编码
+    log.info("md5", crypto.md5("abc"))
+    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
+
+    -- SHA1/哈希SHA1,输出结果已经hex编码
+    log.info("sha1", crypto.sha1("abc"))
+    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
+
+    -- SHA256/哈希SHA256,输出结果已经hex编码
+    log.info("sha256", crypto.sha256("abc"))
+    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
+
+    -- SHA512/哈希SHA512,输出结果已经hex编码
+    log.info("sha512", crypto.sha512("abc"))
+    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
+
+	-- AES加密, 未经Hex编码. AES-128-ECB 算法 对称加密,对齐方式:"ZERO"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_decrypt)
+
+    -- AES加密, 未经Hex编码. AES-128-ECB/CBC 算法 对称加密,对齐方式:"PKCS7"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
+    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
+
+    -- AES解密, 未经Hex编码, AES-128-ECB/CBC 算法 对称解密,,对齐方式:"PKCS7"
+    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
+    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_decrypt)
+    log.info("AES", "aes-128-cbc", data2_decrypt)
+    log.info("mem", rtos.meminfo("sys"))
+
+    -- DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
+    if data1 then 
+        log.info("des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
+        log.info("des", data2)
+    else
+        log.info("des", "当前固件不支持DES/3DES")
+    end
+
+    -- 3DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
+    if data1 then 
+        log.info("3des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
+        log.info("3des", data2)
+    else
+        log.info("3des", "当前固件不支持DES/3DES")
+    end
+  
+    -- 计算CRC16
+    local originStr = "123456sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc16 = crypto.crc16("MODBUS",originStr)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC16 modbus
+    local crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234")
+    log.info("crc16", crc16)
+    crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234", 0xFFFF)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC32
+    local data = "123456sdfdsfdsfdsffdsfdsfsdfs1234" 
+    local crc32 = crypto.crc32(data)
+    log.info("crc32", crc32) --21438764
+    -- start和poly可选, 是 2025.4.14 新增的参数
+    local crc32 = crypto.crc32(data, 0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF) --等同于crypto.crc32(data)
+    log.info("crc32", crc32)
+
+    -- 计算CRC8
+    local data= "sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc8 = crypto.crc8(data)
+    log.info("crc8", crc8)
+    local crc8 = crypto.crc8(data, 0x31, 0xff, false)
+    log.info("crc8", crc8)  
+        
+    -- 计算CRC7
+    if crypto.crc7 then
+        local result = crypto.crc7("abc", 0xE5, 0x00)
+        log.info("crc7", result, string.format("%02X", result))  --50 32
+    else
+        log.info("crypto", "当前固件不支持crypto.crc7")
+    end
+    
+    log.info("随机数测试")
+    for i=1, 10 do
+        sys.wait(100)
+        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
+        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
+        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
+    end
+
+    -- totp的密钥
+    log.info("totp的密钥")
+    local secret = "VK54ZXPO74ISEM2E"
+    --写死时间戳用来测试
+    local ts = 1646796576
+    --生成十分钟的动态码验证下
+    for i=1,600,30 do
+        local r = crypto.totp(secret,ts+i)
+        local time = os.date("*t",ts+i + 8*3600)--东八区
+        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
+    end
+    
+    --将数据进行base64编码
+    -- 本函数与 string.toBase64 是同一个
+    local bdata = crypto.base64_encode("123")
+    log.info("base64", "encode", bdata)
+    
+    --将数据进行base64解码
+    -- 本函数与 string.fromBase64 是同一个
+    local data = crypto.base64_decode("MTIz")
+    log.info("base64", "decode", bdata, data)--123    
+
+    -- 打印所有支持的cipher
+    if crypto.cipher_list then
+        log.info("cipher", "list", json.encode(crypto.cipher_list()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_list")
+    end
+    -- 打印所有支持的cipher suites
+    if crypto.cipher_suites then
+        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_suites")
+    end
+    
+    -- 计算文件的hash值(md5/sha1/sha256及hmac形式)
+    log.info("文件hash值测试")
+    if crypto.md_file then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
+        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
+        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
+    else
+        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
+    end
+    
+    --计算数据的hash值(md5/sha1/sha256及hmac形式)
+    if crypto.md then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md("MD5", "1234567890"))
+        log.info("sha1", crypto.md("SHA1", "1234567890"))
+        log.info("sha256", crypto.md("SHA256", "1234567890"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
+        log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
+        log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
+    else
+        log.info("数据hash值测试", "当前固件不支持crypto.md")    
+    end
+    
+    -- 流式hash测试
+    log.info("流式hash测试")
+    if crypto.hash_init then
+        -- MD5
+        local md5_obj = crypto.hash_init("MD5")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        local md5_result = crypto.hash_finish(md5_obj)
+        log.info("md5_stream", md5_result)
+        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
+
+        -- HMAC_MD5
+        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
+        log.info("hmac_md5_stream", hmac_md5_result)
+        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA1
+        local sha1_obj = crypto.hash_init("SHA1")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        local sha1_result = crypto.hash_finish(sha1_obj)
+        log.info("sha1_stream", sha1_result)
+        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA1
+        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
+        log.info("hmac_sha1_stream", hmac_sha1_result)
+        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA256
+        local sha256_obj = crypto.hash_init("SHA256")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        local sha256_result = crypto.hash_finish(sha256_obj)
+        log.info("sha256_stream", sha256_result)
+        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA256
+        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
+        log.info("hmac_sha256_stream", hmac_sha256_result)
+        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA512
+        local sha512_obj = crypto.hash_init("SHA512")
+        if sha512_obj then
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            local sha512_result = crypto.hash_finish(sha512_obj)
+            log.info("sha512_stream", sha512_result)
+            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
+        end
+
+        -- HMAC_SHA512
+        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
+        if hmac_sha512_obj then
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
+            log.info("hmac_sha512_stream", hmac_sha512_result)
+            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
+        end
+    else
+        log.info("crypto", "当前固件不支持crypto.hash_init")
+    end
+   
+    if crypto.checksum then
+        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
+        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
+    else
+        log.info("checksum", "当前固件不支持crypto.checksum")
+    end    
+
+    log.info("crypto", "ALL Done")
+    sys.wait(100000)
+end    
+
+--创建一个task,并且运行task的主函数crypto_task_func
+sys.taskInit(crypto_task_func)

+ 55 - 226
module/Air780EHM_Air780EHV_Air780EGH/demo/crypto/main.lua

@@ -1,242 +1,71 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "cryptodemo"
-VERSION = "1.0.0"
-
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本demo演示的核心功能为:
+演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和
+更多说明参考本目录下的readme.md文件
+]]
+
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "luatos_crypto_app"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
 log.info("main", PROJECT, VERSION)
 
--- sys库是标配
-_G.sys = require("sys")
-
--- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
-if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
-    pm.power(pm.PWK_MODE, false)
-end
-
 
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
 if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
 end
 
-sys.taskInit(function()
-
-    sys.wait(1000)
-
-    -- MD5,输出结果已经hex编码
-    log.info("md5", crypto.md5("abc"))
-    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
-
-    -- SHA1,输出结果已经hex编码
-    log.info("sha1", crypto.sha1("abc"))
-    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
-
-    -- SHA256,输出结果已经hex编码
-    log.info("sha256", crypto.sha256("abc"))
-    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
-
-    -- SHA512,输出结果已经hex编码
-    log.info("sha512", crypto.sha512("abc"))
-    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
-
-	local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
-	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
-	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
-	log.info("AES", "aes-128-ecb", data_decrypt)
-
-    -- AES加密, 未经Hex编码. AES-128-ECB 算法
-    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
-    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
-    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
-    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
-
-    -- AES解密, 未经Hex编码
-    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
-    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
-    log.info("AES", "aes-128-ecb", data_decrypt)
-    log.info("AES", "aes-128-cbc", data2_decrypt)
-    log.info("mem", rtos.meminfo("sys"))
-
-    -- DES-ECB 加解密
-    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
-    if data1 then -- DES-ECB 在某些平台不支持的
-        log.info("des", data1:toHex())
-        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
-        log.info("des", data2)
-    else
-        log.info("des", "当前固件不支持DES/3DES")
-    end
-
-    -- 3DES-ECB 加解密
-    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
-    if data1 then -- DES-ECB 在某些平台不支持的
-        log.info("3des", data1:toHex())
-        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
-        log.info("3des", data2)
-    else
-        log.info("3des", "当前固件不支持DES/3DES")
-    end
-
-
-    -- 打印所有支持的cipher
-    if crypto.cipher_list then
-        log.info("cipher", "list", json.encode(crypto.cipher_list()))
-    else
-        log.info("cipher", "当前固件不支持crypto.cipher_list")
-    end
-    -- 打印所有支持的cipher suites
-    if crypto.cipher_suites then
-        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
-    else
-        log.info("cipher", "当前固件不支持crypto.cipher_suites")
-    end
-
-    ---------------------------------------
-    log.info("随机数测试")
-    for i=1, 10 do
-        sys.wait(100)
-        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
-        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
-        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
-    end
-
-    -- totp的密钥
-    log.info("totp的密钥")
-    local secret = "VK54ZXPO74ISEM2E"
-    --写死时间戳用来测试
-    local ts = 1646796576
-    --生成十分钟的动态码验证下
-    for i=1,600,30 do
-        local r = crypto.totp(secret,ts+i)
-        local time = os.date("*t",ts+i + 8*3600)--东八区
-        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
-    end
-
-    -- 文件测试
-    log.info("文件hash值测试")
-    if crypto.md_file then
-        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
-        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
-        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
-        
-        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
-        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
-        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
-    else
-        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
-    end
-
-    if crypto.checksum then
-        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
-        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
-    else
-        log.info("checksum", "当前固件不支持crypto.checksum")
-    end
-
-    -- 流式hash测试
-    log.info("流式hash测试")
-    if crypto.hash_init then
-        -- MD5
-        local md5_obj = crypto.hash_init("MD5")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        local md5_result = crypto.hash_finish(md5_obj)
-        log.info("md5_stream", md5_result)
-        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
-
-        -- HMAC_MD5
-        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
-        log.info("hmac_md5_stream", hmac_md5_result)
-        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
-
-        -- SHA1
-        local sha1_obj = crypto.hash_init("SHA1")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        local sha1_result = crypto.hash_finish(sha1_obj)
-        log.info("sha1_stream", sha1_result)
-        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
-
-        -- HMAC_SHA1
-        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
-        log.info("hmac_sha1_stream", hmac_sha1_result)
-        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
 
-        -- SHA256
-        local sha256_obj = crypto.hash_init("SHA256")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        local sha256_result = crypto.hash_finish(sha256_obj)
-        log.info("sha256_stream", sha256_result)
-        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
 
-        -- HMAC_SHA256
-        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
-        log.info("hmac_sha256_stream", hmac_sha256_result)
-        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
 
-        -- SHA512
-        local sha512_obj = crypto.hash_init("SHA512")
-        if sha512_obj then
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            local sha512_result = crypto.hash_finish(sha512_obj)
-            log.info("sha512_stream", sha512_result)
-            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
-        end
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
 
-        -- HMAC_SHA512
-        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
-        if hmac_sha512_obj then
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
-            log.info("hmac_sha512_stream", hmac_sha512_result)
-            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
-        end
-    else
-        log.info("crypto", "当前固件不支持crypto.hash_init")
-    end
 
-    log.info("crc7测试")
-    if crypto.crc7 then
-        local result = crypto.crc7(string.char(0xAA), 0xE5, 0x00)
-        log.info("crc7测试", result, string.format("%02X", result))
-    else
-        log.info("crypto", "当前固件不支持crypto.crc7")
-    end
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
 
-    log.info("crypto", "ALL Done")
-    sys.wait(100000)
-end)
+-- 加载crypto_app应用功能模块
+require "crypto_app"
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句
 sys.run()
--- sys.run()之后后面不要加任何语句!!!!!
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 152 - 0
module/Air780EHM_Air780EHV_Air780EGH/demo/crypto/readme.md

@@ -0,0 +1,152 @@
+## 功能模块介绍
+
+1、main.lua:主程序入口;
+
+2、crypto_app.lua:演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+3、logo.jpg:待加密文件
+
+## 演示功能概述
+
+1、创建一个task;
+
+2、演示有关加解密的各种 API 的功能;
+
+
+## 演示硬件环境
+
+![](https://docs.openluat.com/air780ehv/luatos/common/hwenv/image/Air780EHV2.png)
+
+1、Air780EHM/Air780EHV/Air780EGH核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、Air780EHM/Air780EHV/Air780EGH核心板和数据线的硬件接线方式为
+
+- Air780EHM/Air780EHV/Air780EGH核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
+- 核心板正面的 ON/OFF 拨动开关 拨到ON一端;
+
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air780ehv/luatos/common/download/)
+
+2、[Air780EHM 最新版本的内核固件](https://docs.openluat.com/air780epm/luatos/firmware/version/)
+
+3、[Air780EHV 最新版本的内核固件](https://docs.openluat.com/air780ehv/luatos/firmware/version/)
+
+4、[Air780EGH 最新版本的内核固件](https://docs.openluat.com/air780egh/luatos/firmware/version/)
+
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools烧录内核固件和demo脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、出现类似于下面的日志,就表示运行成功:
+
+``` lua
+[2025-10-16 15:00:32.204][000000000.203] I/user.main luatos_crypto_app 001.000.000
+[2025-10-16 15:00:32.794][000000001.212] I/user.md5 900150983CD24FB0D6963F7D28E17F72
+[2025-10-16 15:00:32.794][000000001.213] I/user.hmac_md5 416478FC0ACE1C4AB37F85F4F86A16B1
+[2025-10-16 15:00:32.794][000000001.213] I/user.sha1 A9993E364706816ABA3E25717850C26C9CD0D89D
+[2025-10-16 15:00:32.805][000000001.214] I/user.hmac_sha1 DAE54822C0DAF6C115C97B0AD62C7BCBE9D5E6FC
+[2025-10-16 15:00:32.810][000000001.214] I/user.sha256 BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
+[2025-10-16 15:00:32.814][000000001.215] I/user.hmac_sha256 86055184805B4A466A7BE398FF4A7159F9055EA7EEF339FC94DCEC6F165898BA
+[2025-10-16 15:00:32.814][000000001.216] I/user.sha512 DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F
+[2025-10-16 15:00:32.826][000000001.217] I/user.hmac_sha512 0F92B9AC88949E0BF7C9F1E6F9901BAB8EDFDC9E561DFDE428BC4339961A0569AD01B44343AA56E439949655D15C4D28492D459E75015489920243F3C9986F2A
+[2025-10-16 15:00:32.834][000000001.217] D/crypto zero padding
+[2025-10-16 15:00:32.842][000000001.218] I/user.AES aes-128-ecb 013EEA6EBACCBD7AD990FAEF75FB99C4 32
+[2025-10-16 15:00:32.844][000000001.218] I/user.AES aes-128-ecb 023001
+[2025-10-16 15:00:32.844][000000001.219] I/user.AES aes-128-ecb A37DE67837A1A3006E47A7BC25AA0ECC030B4E058E1972FE5B257FD8C3436142 64
+[2025-10-16 15:00:32.858][000000001.219] I/user.AES aes-128-cbc 26D98EA512AE92BC487536B83F2BE99B467649A9700338F4B4FF75AA2654DD2C 64
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-ecb 12345678901234 > 123456
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-cbc 12345678901234 > 123456
+[2025-10-16 15:00:32.874][000000001.220] I/user.mem 2376584 49564 58880
+[2025-10-16 15:00:32.884][000000001.221] I/user.des 486CB8B81CACCDB7 16
+[2025-10-16 15:00:32.889][000000001.221] I/user.des abcdefg
+[2025-10-16 15:00:32.894][000000001.222] I/user.3des 14619F067B425995D0CD975B85491D98 32
+[2025-10-16 15:00:32.894][000000001.223] I/user.3des abcdefg!!--ZZSS
+[2025-10-16 15:00:32.894][000000001.223] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.914][000000001.224] I/user.crc32 21438764
+[2025-10-16 15:00:32.914][000000001.225] I/user.crc32 21438764
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 197
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 243
+[2025-10-16 15:00:32.937][000000001.226] I/user.crc7 50 32
+[2025-10-16 15:00:32.937][000000001.226] I/user.随机数测试
+[2025-10-16 15:00:32.944][000000001.334] I/user.crypto 真随机数 -939521674 5
+[2025-10-16 15:00:33.016][000000001.434] I/user.crypto 真随机数 -1872085296 5
+[2025-10-16 15:00:33.111][000000001.534] I/user.crypto 真随机数 517455164 5
+[2025-10-16 15:00:33.223][000000001.634] I/user.crypto 真随机数 657132096 5
+[2025-10-16 15:00:33.311][000000001.734] I/user.crypto 真随机数 -1080191914 5
+[2025-10-16 15:00:33.421][000000001.834] I/user.crypto 真随机数 -833578535 5
+[2025-10-16 15:00:33.532][000000001.942] I/user.crypto 真随机数 420499958 5
+[2025-10-16 15:00:33.626][000000002.042] I/user.crypto 真随机数 1233025030 5
+[2025-10-16 15:00:33.720][000000002.142] I/user.crypto 真随机数 2138275442 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.crypto 真随机数 182791818 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.totp的密钥
+[2025-10-16 15:00:33.830][000000002.243] I/user.totp 522113 19 29 37
+[2025-10-16 15:00:33.830][000000002.244] I/user.totp 964300 19 30 7
+[2025-10-16 15:00:33.830][000000002.245] I/user.totp 987714 19 30 37
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 037499 19 31 7
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 699697 19 31 37
+[2025-10-16 15:00:33.830][000000002.247] I/user.totp 548191 19 32 7
+[2025-10-16 15:00:33.845][000000002.248] I/user.totp 747517 19 32 37
+[2025-10-16 15:00:33.845][000000002.249] I/user.totp 243319 19 33 7
+[2025-10-16 15:00:33.861][000000002.249] I/user.totp 147474 19 33 37
+[2025-10-16 15:00:33.877][000000002.250] I/user.totp 039992 19 34 7
+[2025-10-16 15:00:33.877][000000002.251] I/user.totp 628512 19 34 37
+[2025-10-16 15:00:33.877][000000002.252] I/user.totp 529018 19 35 7
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 994006 19 35 37
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 851359 19 36 7
+[2025-10-16 15:00:33.907][000000002.254] I/user.totp 943237 19 36 37
+[2025-10-16 15:00:33.908][000000002.255] I/user.totp 410702 19 37 7
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 082993 19 37 37
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 193281 19 38 7
+[2025-10-16 15:00:33.908][000000002.257] I/user.totp 781573 19 38 37
+[2025-10-16 15:00:33.924][000000002.258] I/user.totp 243288 19 39 7
+[2025-10-16 15:00:33.924][000000002.258] I/user.base64 encode MTIz
+[2025-10-16 15:00:33.924][000000002.259] I/user.base64 decode MTIz 123
+[2025-10-16 15:00:33.924][000000002.260] I/user.cipher list ["AES-128-ECB","AES-192-ECB","AES-256-ECB","AES-128-CBC","AES-192-CBC","AES-256-CBC","AES-128-CTR","AES-192-CTR","AES-256-CTR","AES-128-GCM","AES-192-GCM","AES-256-GCM","AES-128-CCM","AES-192-CCM","AES-256-CCM","DES-ECB","DES-EDE-ECB","DES-EDE3-ECB","DES-CBC","DES-EDE-CBC","DES-EDE3-CBC"]
+[2025-10-16 15:00:33.939][000000002.266] I/user.cipher suites 
+[2025-10-16 15:00:33.939][000000002.266] ["TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CCM","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8","TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CCM","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8","TLS-RSA-WITH-AES-256-GCM-SHA384","TLS-RSA-WITH-AES-256-CCM","TLS-RSA-WITH-AES-256-CBC-SHA256","TLS-RSA-WITH-AES-256-CBC-SHA","TLS-RSA-WITH-AES-256-CCM-8","TLS-RSA-WITH-AES-128-GCM-SHA256","TLS-RSA-WITH-AES-128-CCM","TLS-RSA-WITH-AES-128-CBC-SHA256","TLS-RSA-WITH-AES-128-CBC-SHA","TLS-RSA-WITH-AES-128-CCM-8","TLS-RSA-PSK-WITH-AES-256-GCM-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA","TLS-RSA-PSK-WITH-AES-128-GCM-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-256-GCM-SHA384","TLS-PSK-WITH-AES-256-CCM","TLS-PSK-WITH-AES-256-CBC-SHA384","TLS-PSK-WITH-AES-256-CBC-SHA","TLS-PSK-WITH-AES-256-CCM-8","TLS-PSK-WITH-AES-128-GCM-SHA256","TLS-PSK-WITH-AES-128-CCM","TLS-PSK-WITH-AES-128-CBC-SHA256","TLS-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-128-CCM-8"]
+[2025-10-16 15:00:33.955][000000002.266] I/user.文件hash值测试
+[2025-10-16 15:00:33.955][000000002.269] I/user.md5 D364D04CCD734D2757B25F3216CC431B
+[2025-10-16 15:00:33.955][000000002.273] I/user.sha1 04DA64874D415B1FB9CDD2E89927397D8F48C441
+[2025-10-16 15:00:33.955][000000002.284] I/user.sha256 0C601722B4BD2BC1A76BC3701F4EB646F5119C31702852978C326CD8D7C9212C
+[2025-10-16 15:00:33.955][000000002.287] I/user.hmac_md5 B5F5A687DB904DB67D3311899932DD61
+[2025-10-16 15:00:33.955][000000002.290] I/user.hmac_sha1 2A0B55C290D54ADF2F185EAE460254D267C7CE1F
+[2025-10-16 15:00:33.971][000000002.301] I/user.hmac_sha256 6E443C84D4D7A4721A9A195EB9038EDCFA8A8F60A3F1E8A0090B57B3BAB4942E
+[2025-10-16 15:00:33.971][000000002.301] I/user.md5
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha1
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha256
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_md5
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_sha1
+[2025-10-16 15:00:33.971][000000002.304] I/user.hmac_sha256
+[2025-10-16 15:00:33.971][000000002.304] I/user.流式hash测试
+[2025-10-16 15:00:33.986][000000002.304] I/user.md5_stream F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.305] I/user.md5 F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5_stream 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1_stream C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1 C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1_stream 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256_stream A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256 A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.310] I/user.hmac_sha256_stream EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.hmac_sha256 EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.sha512_stream 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.312] I/user.sha512 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.313] I/user.hmac_sha512_stream 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.314] I/user.hmac_sha512 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum OK 04 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum 357E E4 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.crypto ALL Done
+
+```

+ 282 - 0
module/Air780EPM/demo/crypto/crypto_app.lua

@@ -0,0 +1,282 @@
+--[[
+@module  crypto_app
+@summary crypto_app应用功能模块 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本文件为crypto_app应用功能模块,核心业务逻辑为:
+1、演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+本文件没有对外接口,直接在main.lua中require "crypto_app"就可以加载运行;
+]]
+
+--加密运算主函数
+local function crypto_task_func()
+
+    -- MD5/哈希MD5,输出结果已经hex编码
+    log.info("md5", crypto.md5("abc"))
+    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
+
+    -- SHA1/哈希SHA1,输出结果已经hex编码
+    log.info("sha1", crypto.sha1("abc"))
+    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
+
+    -- SHA256/哈希SHA256,输出结果已经hex编码
+    log.info("sha256", crypto.sha256("abc"))
+    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
+
+    -- SHA512/哈希SHA512,输出结果已经hex编码
+    log.info("sha512", crypto.sha512("abc"))
+    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
+
+	-- AES加密, 未经Hex编码. AES-128-ECB 算法 对称加密,对齐方式:"ZERO"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_decrypt)
+
+    -- AES加密, 未经Hex编码. AES-128-ECB/CBC 算法 对称加密,对齐方式:"PKCS7"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
+    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
+
+    -- AES解密, 未经Hex编码, AES-128-ECB/CBC 算法 对称解密,,对齐方式:"PKCS7"
+    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
+    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_decrypt)
+    log.info("AES", "aes-128-cbc", data2_decrypt)
+    log.info("mem", rtos.meminfo("sys"))
+
+    -- DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
+    if data1 then 
+        log.info("des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
+        log.info("des", data2)
+    else
+        log.info("des", "当前固件不支持DES/3DES")
+    end
+
+    -- 3DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
+    if data1 then 
+        log.info("3des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
+        log.info("3des", data2)
+    else
+        log.info("3des", "当前固件不支持DES/3DES")
+    end
+  
+    -- 计算CRC16
+    local originStr = "123456sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc16 = crypto.crc16("MODBUS",originStr)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC16 modbus
+    local crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234")
+    log.info("crc16", crc16)
+    crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234", 0xFFFF)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC32
+    local data = "123456sdfdsfdsfdsffdsfdsfsdfs1234" 
+    local crc32 = crypto.crc32(data)
+    log.info("crc32", crc32) --21438764
+    -- start和poly可选, 是 2025.4.14 新增的参数
+    local crc32 = crypto.crc32(data, 0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF) --等同于crypto.crc32(data)
+    log.info("crc32", crc32)
+
+    -- 计算CRC8
+    local data= "sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc8 = crypto.crc8(data)
+    log.info("crc8", crc8)
+    local crc8 = crypto.crc8(data, 0x31, 0xff, false)
+    log.info("crc8", crc8)  
+        
+    -- 计算CRC7
+    if crypto.crc7 then
+        local result = crypto.crc7("abc", 0xE5, 0x00)
+        log.info("crc7", result, string.format("%02X", result))  --50 32
+    else
+        log.info("crypto", "当前固件不支持crypto.crc7")
+    end
+    
+    log.info("随机数测试")
+    for i=1, 10 do
+        sys.wait(100)
+        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
+        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
+        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
+    end
+
+    -- totp的密钥
+    log.info("totp的密钥")
+    local secret = "VK54ZXPO74ISEM2E"
+    --写死时间戳用来测试
+    local ts = 1646796576
+    --生成十分钟的动态码验证下
+    for i=1,600,30 do
+        local r = crypto.totp(secret,ts+i)
+        local time = os.date("*t",ts+i + 8*3600)--东八区
+        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
+    end
+    
+    --将数据进行base64编码
+    -- 本函数与 string.toBase64 是同一个
+    local bdata = crypto.base64_encode("123")
+    log.info("base64", "encode", bdata)
+    
+    --将数据进行base64解码
+    -- 本函数与 string.fromBase64 是同一个
+    local data = crypto.base64_decode("MTIz")
+    log.info("base64", "decode", bdata, data)--123    
+
+    -- 打印所有支持的cipher
+    if crypto.cipher_list then
+        log.info("cipher", "list", json.encode(crypto.cipher_list()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_list")
+    end
+    -- 打印所有支持的cipher suites
+    if crypto.cipher_suites then
+        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_suites")
+    end
+    
+    -- 计算文件的hash值(md5/sha1/sha256及hmac形式)
+    log.info("文件hash值测试")
+    if crypto.md_file then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
+        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
+        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
+    else
+        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
+    end
+    
+    --计算数据的hash值(md5/sha1/sha256及hmac形式)
+    if crypto.md then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md("MD5", "1234567890"))
+        log.info("sha1", crypto.md("SHA1", "1234567890"))
+        log.info("sha256", crypto.md("SHA256", "1234567890"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
+        log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
+        log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
+    else
+        log.info("数据hash值测试", "当前固件不支持crypto.md")    
+    end
+    
+    -- 流式hash测试
+    log.info("流式hash测试")
+    if crypto.hash_init then
+        -- MD5
+        local md5_obj = crypto.hash_init("MD5")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        local md5_result = crypto.hash_finish(md5_obj)
+        log.info("md5_stream", md5_result)
+        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
+
+        -- HMAC_MD5
+        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
+        log.info("hmac_md5_stream", hmac_md5_result)
+        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA1
+        local sha1_obj = crypto.hash_init("SHA1")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        local sha1_result = crypto.hash_finish(sha1_obj)
+        log.info("sha1_stream", sha1_result)
+        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA1
+        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
+        log.info("hmac_sha1_stream", hmac_sha1_result)
+        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA256
+        local sha256_obj = crypto.hash_init("SHA256")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        local sha256_result = crypto.hash_finish(sha256_obj)
+        log.info("sha256_stream", sha256_result)
+        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA256
+        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
+        log.info("hmac_sha256_stream", hmac_sha256_result)
+        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA512
+        local sha512_obj = crypto.hash_init("SHA512")
+        if sha512_obj then
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            local sha512_result = crypto.hash_finish(sha512_obj)
+            log.info("sha512_stream", sha512_result)
+            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
+        end
+
+        -- HMAC_SHA512
+        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
+        if hmac_sha512_obj then
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
+            log.info("hmac_sha512_stream", hmac_sha512_result)
+            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
+        end
+    else
+        log.info("crypto", "当前固件不支持crypto.hash_init")
+    end
+   
+    if crypto.checksum then
+        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
+        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
+    else
+        log.info("checksum", "当前固件不支持crypto.checksum")
+    end    
+
+    log.info("crypto", "ALL Done")
+    sys.wait(100000)
+end    
+
+--创建一个task,并且运行task的主函数crypto_task_func
+sys.taskInit(crypto_task_func)

+ 55 - 226
module/Air780EPM/demo/crypto/main.lua

@@ -1,242 +1,71 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "cryptodemo"
-VERSION = "1.0.0"
-
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本demo演示的核心功能为:
+演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和
+更多说明参考本目录下的readme.md文件
+]]
+
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "luatos_crypto_app"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
 log.info("main", PROJECT, VERSION)
 
--- sys库是标配
-_G.sys = require("sys")
-
--- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
-if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
-    pm.power(pm.PWK_MODE, false)
-end
-
 
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
 if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
 end
 
-sys.taskInit(function()
-
-    sys.wait(1000)
-
-    -- MD5,输出结果已经hex编码
-    log.info("md5", crypto.md5("abc"))
-    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
-
-    -- SHA1,输出结果已经hex编码
-    log.info("sha1", crypto.sha1("abc"))
-    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
-
-    -- SHA256,输出结果已经hex编码
-    log.info("sha256", crypto.sha256("abc"))
-    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
-
-    -- SHA512,输出结果已经hex编码
-    log.info("sha512", crypto.sha512("abc"))
-    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
-
-	local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
-	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
-	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
-	log.info("AES", "aes-128-ecb", data_decrypt)
-
-    -- AES加密, 未经Hex编码. AES-128-ECB 算法
-    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
-    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
-    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
-    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
-
-    -- AES解密, 未经Hex编码
-    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
-    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
-    log.info("AES", "aes-128-ecb", data_decrypt)
-    log.info("AES", "aes-128-cbc", data2_decrypt)
-    log.info("mem", rtos.meminfo("sys"))
-
-    -- DES-ECB 加解密
-    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
-    if data1 then -- DES-ECB 在某些平台不支持的
-        log.info("des", data1:toHex())
-        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
-        log.info("des", data2)
-    else
-        log.info("des", "当前固件不支持DES/3DES")
-    end
-
-    -- 3DES-ECB 加解密
-    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
-    if data1 then -- DES-ECB 在某些平台不支持的
-        log.info("3des", data1:toHex())
-        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
-        log.info("3des", data2)
-    else
-        log.info("3des", "当前固件不支持DES/3DES")
-    end
-
-
-    -- 打印所有支持的cipher
-    if crypto.cipher_list then
-        log.info("cipher", "list", json.encode(crypto.cipher_list()))
-    else
-        log.info("cipher", "当前固件不支持crypto.cipher_list")
-    end
-    -- 打印所有支持的cipher suites
-    if crypto.cipher_suites then
-        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
-    else
-        log.info("cipher", "当前固件不支持crypto.cipher_suites")
-    end
-
-    ---------------------------------------
-    log.info("随机数测试")
-    for i=1, 10 do
-        sys.wait(100)
-        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
-        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
-        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
-    end
-
-    -- totp的密钥
-    log.info("totp的密钥")
-    local secret = "VK54ZXPO74ISEM2E"
-    --写死时间戳用来测试
-    local ts = 1646796576
-    --生成十分钟的动态码验证下
-    for i=1,600,30 do
-        local r = crypto.totp(secret,ts+i)
-        local time = os.date("*t",ts+i + 8*3600)--东八区
-        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
-    end
-
-    -- 文件测试
-    log.info("文件hash值测试")
-    if crypto.md_file then
-        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
-        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
-        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
-        
-        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
-        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
-        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
-    else
-        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
-    end
-
-    if crypto.checksum then
-        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
-        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
-    else
-        log.info("checksum", "当前固件不支持crypto.checksum")
-    end
-
-    -- 流式hash测试
-    log.info("流式hash测试")
-    if crypto.hash_init then
-        -- MD5
-        local md5_obj = crypto.hash_init("MD5")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        local md5_result = crypto.hash_finish(md5_obj)
-        log.info("md5_stream", md5_result)
-        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
-
-        -- HMAC_MD5
-        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
-        log.info("hmac_md5_stream", hmac_md5_result)
-        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
-
-        -- SHA1
-        local sha1_obj = crypto.hash_init("SHA1")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        local sha1_result = crypto.hash_finish(sha1_obj)
-        log.info("sha1_stream", sha1_result)
-        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
-
-        -- HMAC_SHA1
-        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
-        log.info("hmac_sha1_stream", hmac_sha1_result)
-        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
 
-        -- SHA256
-        local sha256_obj = crypto.hash_init("SHA256")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        local sha256_result = crypto.hash_finish(sha256_obj)
-        log.info("sha256_stream", sha256_result)
-        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
 
-        -- HMAC_SHA256
-        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
-        log.info("hmac_sha256_stream", hmac_sha256_result)
-        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
 
-        -- SHA512
-        local sha512_obj = crypto.hash_init("SHA512")
-        if sha512_obj then
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            local sha512_result = crypto.hash_finish(sha512_obj)
-            log.info("sha512_stream", sha512_result)
-            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
-        end
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
 
-        -- HMAC_SHA512
-        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
-        if hmac_sha512_obj then
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
-            log.info("hmac_sha512_stream", hmac_sha512_result)
-            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
-        end
-    else
-        log.info("crypto", "当前固件不支持crypto.hash_init")
-    end
 
-    log.info("crc7测试")
-    if crypto.crc7 then
-        local result = crypto.crc7(string.char(0xAA), 0xE5, 0x00)
-        log.info("crc7测试", result, string.format("%02X", result))
-    else
-        log.info("crypto", "当前固件不支持crypto.crc7")
-    end
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
 
-    log.info("crypto", "ALL Done")
-    sys.wait(100000)
-end)
+-- 加载crypto_app应用功能模块
+require "crypto_app"
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句
 sys.run()
--- sys.run()之后后面不要加任何语句!!!!!
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 148 - 0
module/Air780EPM/demo/crypto/readme.md

@@ -0,0 +1,148 @@
+## 功能模块介绍
+
+1、main.lua:主程序入口;
+
+2、crypto_app.lua:演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+3、logo.jpg:待加密文件
+
+## 演示功能概述
+
+1、创建一个task;
+
+2、演示有关加解密的各种 API 的功能;
+
+
+## 演示硬件环境
+
+![](https://docs.openluat.com/air780epm/luatos/common/hwenv/image/Air780EPM2.png)
+
+1、Air780EPM核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、Air780EPM核心板和数据线的硬件接线方式为
+
+- Air780EPM核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
+- 核心板正面的 ON/OFF 拨动开关 拨到ON一端;
+
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/)
+
+2、[Air780EPM 最新版本的内核固件](https://docs.openluat.com/air780epm/luatos/firmware/version/)
+
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools烧录内核固件和demo脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、出现类似于下面的日志,就表示运行成功:
+
+``` lua
+[2025-10-16 15:00:32.204][000000000.203] I/user.main luatos_crypto_app 001.000.000
+[2025-10-16 15:00:32.794][000000001.212] I/user.md5 900150983CD24FB0D6963F7D28E17F72
+[2025-10-16 15:00:32.794][000000001.213] I/user.hmac_md5 416478FC0ACE1C4AB37F85F4F86A16B1
+[2025-10-16 15:00:32.794][000000001.213] I/user.sha1 A9993E364706816ABA3E25717850C26C9CD0D89D
+[2025-10-16 15:00:32.805][000000001.214] I/user.hmac_sha1 DAE54822C0DAF6C115C97B0AD62C7BCBE9D5E6FC
+[2025-10-16 15:00:32.810][000000001.214] I/user.sha256 BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
+[2025-10-16 15:00:32.814][000000001.215] I/user.hmac_sha256 86055184805B4A466A7BE398FF4A7159F9055EA7EEF339FC94DCEC6F165898BA
+[2025-10-16 15:00:32.814][000000001.216] I/user.sha512 DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F
+[2025-10-16 15:00:32.826][000000001.217] I/user.hmac_sha512 0F92B9AC88949E0BF7C9F1E6F9901BAB8EDFDC9E561DFDE428BC4339961A0569AD01B44343AA56E439949655D15C4D28492D459E75015489920243F3C9986F2A
+[2025-10-16 15:00:32.834][000000001.217] D/crypto zero padding
+[2025-10-16 15:00:32.842][000000001.218] I/user.AES aes-128-ecb 013EEA6EBACCBD7AD990FAEF75FB99C4 32
+[2025-10-16 15:00:32.844][000000001.218] I/user.AES aes-128-ecb 023001
+[2025-10-16 15:00:32.844][000000001.219] I/user.AES aes-128-ecb A37DE67837A1A3006E47A7BC25AA0ECC030B4E058E1972FE5B257FD8C3436142 64
+[2025-10-16 15:00:32.858][000000001.219] I/user.AES aes-128-cbc 26D98EA512AE92BC487536B83F2BE99B467649A9700338F4B4FF75AA2654DD2C 64
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-ecb 12345678901234 > 123456
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-cbc 12345678901234 > 123456
+[2025-10-16 15:00:32.874][000000001.220] I/user.mem 2376584 49564 58880
+[2025-10-16 15:00:32.884][000000001.221] I/user.des 486CB8B81CACCDB7 16
+[2025-10-16 15:00:32.889][000000001.221] I/user.des abcdefg
+[2025-10-16 15:00:32.894][000000001.222] I/user.3des 14619F067B425995D0CD975B85491D98 32
+[2025-10-16 15:00:32.894][000000001.223] I/user.3des abcdefg!!--ZZSS
+[2025-10-16 15:00:32.894][000000001.223] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.914][000000001.224] I/user.crc32 21438764
+[2025-10-16 15:00:32.914][000000001.225] I/user.crc32 21438764
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 197
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 243
+[2025-10-16 15:00:32.937][000000001.226] I/user.crc7 50 32
+[2025-10-16 15:00:32.937][000000001.226] I/user.随机数测试
+[2025-10-16 15:00:32.944][000000001.334] I/user.crypto 真随机数 -939521674 5
+[2025-10-16 15:00:33.016][000000001.434] I/user.crypto 真随机数 -1872085296 5
+[2025-10-16 15:00:33.111][000000001.534] I/user.crypto 真随机数 517455164 5
+[2025-10-16 15:00:33.223][000000001.634] I/user.crypto 真随机数 657132096 5
+[2025-10-16 15:00:33.311][000000001.734] I/user.crypto 真随机数 -1080191914 5
+[2025-10-16 15:00:33.421][000000001.834] I/user.crypto 真随机数 -833578535 5
+[2025-10-16 15:00:33.532][000000001.942] I/user.crypto 真随机数 420499958 5
+[2025-10-16 15:00:33.626][000000002.042] I/user.crypto 真随机数 1233025030 5
+[2025-10-16 15:00:33.720][000000002.142] I/user.crypto 真随机数 2138275442 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.crypto 真随机数 182791818 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.totp的密钥
+[2025-10-16 15:00:33.830][000000002.243] I/user.totp 522113 19 29 37
+[2025-10-16 15:00:33.830][000000002.244] I/user.totp 964300 19 30 7
+[2025-10-16 15:00:33.830][000000002.245] I/user.totp 987714 19 30 37
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 037499 19 31 7
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 699697 19 31 37
+[2025-10-16 15:00:33.830][000000002.247] I/user.totp 548191 19 32 7
+[2025-10-16 15:00:33.845][000000002.248] I/user.totp 747517 19 32 37
+[2025-10-16 15:00:33.845][000000002.249] I/user.totp 243319 19 33 7
+[2025-10-16 15:00:33.861][000000002.249] I/user.totp 147474 19 33 37
+[2025-10-16 15:00:33.877][000000002.250] I/user.totp 039992 19 34 7
+[2025-10-16 15:00:33.877][000000002.251] I/user.totp 628512 19 34 37
+[2025-10-16 15:00:33.877][000000002.252] I/user.totp 529018 19 35 7
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 994006 19 35 37
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 851359 19 36 7
+[2025-10-16 15:00:33.907][000000002.254] I/user.totp 943237 19 36 37
+[2025-10-16 15:00:33.908][000000002.255] I/user.totp 410702 19 37 7
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 082993 19 37 37
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 193281 19 38 7
+[2025-10-16 15:00:33.908][000000002.257] I/user.totp 781573 19 38 37
+[2025-10-16 15:00:33.924][000000002.258] I/user.totp 243288 19 39 7
+[2025-10-16 15:00:33.924][000000002.258] I/user.base64 encode MTIz
+[2025-10-16 15:00:33.924][000000002.259] I/user.base64 decode MTIz 123
+[2025-10-16 15:00:33.924][000000002.260] I/user.cipher list ["AES-128-ECB","AES-192-ECB","AES-256-ECB","AES-128-CBC","AES-192-CBC","AES-256-CBC","AES-128-CTR","AES-192-CTR","AES-256-CTR","AES-128-GCM","AES-192-GCM","AES-256-GCM","AES-128-CCM","AES-192-CCM","AES-256-CCM","DES-ECB","DES-EDE-ECB","DES-EDE3-ECB","DES-CBC","DES-EDE-CBC","DES-EDE3-CBC"]
+[2025-10-16 15:00:33.939][000000002.266] I/user.cipher suites 
+[2025-10-16 15:00:33.939][000000002.266] ["TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CCM","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8","TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CCM","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8","TLS-RSA-WITH-AES-256-GCM-SHA384","TLS-RSA-WITH-AES-256-CCM","TLS-RSA-WITH-AES-256-CBC-SHA256","TLS-RSA-WITH-AES-256-CBC-SHA","TLS-RSA-WITH-AES-256-CCM-8","TLS-RSA-WITH-AES-128-GCM-SHA256","TLS-RSA-WITH-AES-128-CCM","TLS-RSA-WITH-AES-128-CBC-SHA256","TLS-RSA-WITH-AES-128-CBC-SHA","TLS-RSA-WITH-AES-128-CCM-8","TLS-RSA-PSK-WITH-AES-256-GCM-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA","TLS-RSA-PSK-WITH-AES-128-GCM-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-256-GCM-SHA384","TLS-PSK-WITH-AES-256-CCM","TLS-PSK-WITH-AES-256-CBC-SHA384","TLS-PSK-WITH-AES-256-CBC-SHA","TLS-PSK-WITH-AES-256-CCM-8","TLS-PSK-WITH-AES-128-GCM-SHA256","TLS-PSK-WITH-AES-128-CCM","TLS-PSK-WITH-AES-128-CBC-SHA256","TLS-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-128-CCM-8"]
+[2025-10-16 15:00:33.955][000000002.266] I/user.文件hash值测试
+[2025-10-16 15:00:33.955][000000002.269] I/user.md5 D364D04CCD734D2757B25F3216CC431B
+[2025-10-16 15:00:33.955][000000002.273] I/user.sha1 04DA64874D415B1FB9CDD2E89927397D8F48C441
+[2025-10-16 15:00:33.955][000000002.284] I/user.sha256 0C601722B4BD2BC1A76BC3701F4EB646F5119C31702852978C326CD8D7C9212C
+[2025-10-16 15:00:33.955][000000002.287] I/user.hmac_md5 B5F5A687DB904DB67D3311899932DD61
+[2025-10-16 15:00:33.955][000000002.290] I/user.hmac_sha1 2A0B55C290D54ADF2F185EAE460254D267C7CE1F
+[2025-10-16 15:00:33.971][000000002.301] I/user.hmac_sha256 6E443C84D4D7A4721A9A195EB9038EDCFA8A8F60A3F1E8A0090B57B3BAB4942E
+[2025-10-16 15:00:33.971][000000002.301] I/user.md5
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha1
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha256
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_md5
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_sha1
+[2025-10-16 15:00:33.971][000000002.304] I/user.hmac_sha256
+[2025-10-16 15:00:33.971][000000002.304] I/user.流式hash测试
+[2025-10-16 15:00:33.986][000000002.304] I/user.md5_stream F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.305] I/user.md5 F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5_stream 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1_stream C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1 C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1_stream 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256_stream A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256 A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.310] I/user.hmac_sha256_stream EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.hmac_sha256 EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.sha512_stream 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.312] I/user.sha512 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.313] I/user.hmac_sha512_stream 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.314] I/user.hmac_sha512 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum OK 04 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum 357E E4 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.crypto ALL Done
+
+```

+ 282 - 0
module/Air8000/demo/crypto/crypto_app.lua

@@ -0,0 +1,282 @@
+--[[
+@module  crypto_app
+@summary crypto_app应用功能模块 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本文件为crypto_app应用功能模块,核心业务逻辑为:
+1、演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+本文件没有对外接口,直接在main.lua中require "crypto_app"就可以加载运行;
+]]
+
+--加密运算主函数
+local function crypto_task_func()
+
+    -- MD5/哈希MD5,输出结果已经hex编码
+    log.info("md5", crypto.md5("abc"))
+    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
+
+    -- SHA1/哈希SHA1,输出结果已经hex编码
+    log.info("sha1", crypto.sha1("abc"))
+    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
+
+    -- SHA256/哈希SHA256,输出结果已经hex编码
+    log.info("sha256", crypto.sha256("abc"))
+    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
+
+    -- SHA512/哈希SHA512,输出结果已经hex编码
+    log.info("sha512", crypto.sha512("abc"))
+    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
+
+	-- AES加密, 未经Hex编码. AES-128-ECB 算法 对称加密,对齐方式:"ZERO"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_decrypt)
+
+    -- AES加密, 未经Hex编码. AES-128-ECB/CBC 算法 对称加密,对齐方式:"PKCS7"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
+    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
+
+    -- AES解密, 未经Hex编码, AES-128-ECB/CBC 算法 对称解密,,对齐方式:"PKCS7"
+    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
+    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_decrypt)
+    log.info("AES", "aes-128-cbc", data2_decrypt)
+    log.info("mem", rtos.meminfo("sys"))
+
+    -- DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
+    if data1 then 
+        log.info("des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
+        log.info("des", data2)
+    else
+        log.info("des", "当前固件不支持DES/3DES")
+    end
+
+    -- 3DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
+    if data1 then 
+        log.info("3des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
+        log.info("3des", data2)
+    else
+        log.info("3des", "当前固件不支持DES/3DES")
+    end
+  
+    -- 计算CRC16
+    local originStr = "123456sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc16 = crypto.crc16("MODBUS",originStr)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC16 modbus
+    local crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234")
+    log.info("crc16", crc16)
+    crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234", 0xFFFF)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC32
+    local data = "123456sdfdsfdsfdsffdsfdsfsdfs1234" 
+    local crc32 = crypto.crc32(data)
+    log.info("crc32", crc32) --21438764
+    -- start和poly可选, 是 2025.4.14 新增的参数
+    local crc32 = crypto.crc32(data, 0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF) --等同于crypto.crc32(data)
+    log.info("crc32", crc32)
+
+    -- 计算CRC8
+    local data= "sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc8 = crypto.crc8(data)
+    log.info("crc8", crc8)
+    local crc8 = crypto.crc8(data, 0x31, 0xff, false)
+    log.info("crc8", crc8)  
+        
+    -- 计算CRC7
+    if crypto.crc7 then
+        local result = crypto.crc7("abc", 0xE5, 0x00)
+        log.info("crc7", result, string.format("%02X", result))  --50 32
+    else
+        log.info("crypto", "当前固件不支持crypto.crc7")
+    end
+    
+    log.info("随机数测试")
+    for i=1, 10 do
+        sys.wait(100)
+        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
+        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
+        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
+    end
+
+    -- totp的密钥
+    log.info("totp的密钥")
+    local secret = "VK54ZXPO74ISEM2E"
+    --写死时间戳用来测试
+    local ts = 1646796576
+    --生成十分钟的动态码验证下
+    for i=1,600,30 do
+        local r = crypto.totp(secret,ts+i)
+        local time = os.date("*t",ts+i + 8*3600)--东八区
+        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
+    end
+    
+    --将数据进行base64编码
+    -- 本函数与 string.toBase64 是同一个
+    local bdata = crypto.base64_encode("123")
+    log.info("base64", "encode", bdata)
+    
+    --将数据进行base64解码
+    -- 本函数与 string.fromBase64 是同一个
+    local data = crypto.base64_decode("MTIz")
+    log.info("base64", "decode", bdata, data)--123    
+
+    -- 打印所有支持的cipher
+    if crypto.cipher_list then
+        log.info("cipher", "list", json.encode(crypto.cipher_list()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_list")
+    end
+    -- 打印所有支持的cipher suites
+    if crypto.cipher_suites then
+        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_suites")
+    end
+    
+    -- 计算文件的hash值(md5/sha1/sha256及hmac形式)
+    log.info("文件hash值测试")
+    if crypto.md_file then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
+        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
+        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
+    else
+        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
+    end
+    
+    --计算数据的hash值(md5/sha1/sha256及hmac形式)
+    if crypto.md then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md("MD5", "1234567890"))
+        log.info("sha1", crypto.md("SHA1", "1234567890"))
+        log.info("sha256", crypto.md("SHA256", "1234567890"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
+        log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
+        log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
+    else
+        log.info("数据hash值测试", "当前固件不支持crypto.md")    
+    end
+    
+    -- 流式hash测试
+    log.info("流式hash测试")
+    if crypto.hash_init then
+        -- MD5
+        local md5_obj = crypto.hash_init("MD5")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        local md5_result = crypto.hash_finish(md5_obj)
+        log.info("md5_stream", md5_result)
+        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
+
+        -- HMAC_MD5
+        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
+        log.info("hmac_md5_stream", hmac_md5_result)
+        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA1
+        local sha1_obj = crypto.hash_init("SHA1")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        local sha1_result = crypto.hash_finish(sha1_obj)
+        log.info("sha1_stream", sha1_result)
+        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA1
+        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
+        log.info("hmac_sha1_stream", hmac_sha1_result)
+        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA256
+        local sha256_obj = crypto.hash_init("SHA256")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        local sha256_result = crypto.hash_finish(sha256_obj)
+        log.info("sha256_stream", sha256_result)
+        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA256
+        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
+        log.info("hmac_sha256_stream", hmac_sha256_result)
+        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA512
+        local sha512_obj = crypto.hash_init("SHA512")
+        if sha512_obj then
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            local sha512_result = crypto.hash_finish(sha512_obj)
+            log.info("sha512_stream", sha512_result)
+            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
+        end
+
+        -- HMAC_SHA512
+        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
+        if hmac_sha512_obj then
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
+            log.info("hmac_sha512_stream", hmac_sha512_result)
+            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
+        end
+    else
+        log.info("crypto", "当前固件不支持crypto.hash_init")
+    end
+   
+    if crypto.checksum then
+        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
+        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
+    else
+        log.info("checksum", "当前固件不支持crypto.checksum")
+    end    
+
+    log.info("crypto", "ALL Done")
+    sys.wait(100000)
+end    
+
+--创建一个task,并且运行task的主函数crypto_task_func
+sys.taskInit(crypto_task_func)

+ 55 - 222
module/Air8000/demo/crypto/main.lua

@@ -1,238 +1,71 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "cryptodemo"
-VERSION = "1.0.0"
-
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本demo演示的核心功能为:
+演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和
+更多说明参考本目录下的readme.md文件
+]]
+
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "luatos_crypto_app"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
 log.info("main", PROJECT, VERSION)
 
--- sys库是标配
-_G.sys = require("sys")
-
-
 
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
 if wdt then
-    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
-    wdt.init(9000)--初始化watchdog设置为9s
-    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
 end
 
-sys.taskInit(function()
-
-    sys.wait(1000)
-
-    -- MD5,输出结果已经hex编码
-    log.info("md5", crypto.md5("abc"))
-    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
-
-    -- SHA1,输出结果已经hex编码
-    log.info("sha1", crypto.sha1("abc"))
-    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
-
-    -- SHA256,输出结果已经hex编码
-    log.info("sha256", crypto.sha256("abc"))
-    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
-
-    -- SHA512,输出结果已经hex编码
-    log.info("sha512", crypto.sha512("abc"))
-    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
-
-	local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
-	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
-	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
-	log.info("AES", "aes-128-ecb", data_decrypt)
-
-    -- AES加密, 未经Hex编码. AES-128-ECB 算法
-    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
-    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
-    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
-    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
-
-    -- AES解密, 未经Hex编码
-    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
-    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
-    log.info("AES", "aes-128-ecb", data_decrypt)
-    log.info("AES", "aes-128-cbc", data2_decrypt)
-    log.info("mem", rtos.meminfo("sys"))
-
-    -- DES-ECB 加解密
-    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
-    if data1 then -- DES-ECB 在某些平台不支持的
-        log.info("des", data1:toHex())
-        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
-        log.info("des", data2)
-    else
-        log.info("des", "当前固件不支持DES/3DES")
-    end
-
-    -- 3DES-ECB 加解密
-    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
-    if data1 then -- DES-ECB 在某些平台不支持的
-        log.info("3des", data1:toHex())
-        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
-        log.info("3des", data2)
-    else
-        log.info("3des", "当前固件不支持DES/3DES")
-    end
-
-
-    -- 打印所有支持的cipher
-    if crypto.cipher_list then
-        log.info("cipher", "list", json.encode(crypto.cipher_list()))
-    else
-        log.info("cipher", "当前固件不支持crypto.cipher_list")
-    end
-    -- 打印所有支持的cipher suites
-    if crypto.cipher_suites then
-        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
-    else
-        log.info("cipher", "当前固件不支持crypto.cipher_suites")
-    end
-
-    ---------------------------------------
-    log.info("随机数测试")
-    for i=1, 10 do
-        sys.wait(100)
-        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
-        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
-        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
-    end
-
-    -- totp的密钥
-    log.info("totp的密钥")
-    local secret = "VK54ZXPO74ISEM2E"
-    --写死时间戳用来测试
-    local ts = 1646796576
-    --生成十分钟的动态码验证下
-    for i=1,600,30 do
-        local r = crypto.totp(secret,ts+i)
-        local time = os.date("*t",ts+i + 8*3600)--东八区
-        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
-    end
-
-    -- 文件测试
-    log.info("文件hash值测试")
-    if crypto.md_file then
-        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
-        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
-        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
-        
-        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
-        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
-        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
-    else
-        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
-    end
-
-    if crypto.checksum then
-        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
-        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
-    else
-        log.info("checksum", "当前固件不支持crypto.checksum")
-    end
-
-    -- 流式hash测试
-    log.info("流式hash测试")
-    if crypto.hash_init then
-        -- MD5
-        local md5_obj = crypto.hash_init("MD5")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        crypto.hash_update(md5_obj, "1234567890")
-        local md5_result = crypto.hash_finish(md5_obj)
-        log.info("md5_stream", md5_result)
-        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
-
-        -- HMAC_MD5
-        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        crypto.hash_update(hmac_md5_obj, "1234567890")
-        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
-        log.info("hmac_md5_stream", hmac_md5_result)
-        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
-
-        -- SHA1
-        local sha1_obj = crypto.hash_init("SHA1")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        crypto.hash_update(sha1_obj, "1234567890")
-        local sha1_result = crypto.hash_finish(sha1_obj)
-        log.info("sha1_stream", sha1_result)
-        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
-
-        -- HMAC_SHA1
-        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        crypto.hash_update(hmac_sha1_obj, "1234567890")
-        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
-        log.info("hmac_sha1_stream", hmac_sha1_result)
-        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
 
-        -- SHA256
-        local sha256_obj = crypto.hash_init("SHA256")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        crypto.hash_update(sha256_obj, "1234567890")
-        local sha256_result = crypto.hash_finish(sha256_obj)
-        log.info("sha256_stream", sha256_result)
-        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
 
-        -- HMAC_SHA256
-        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        crypto.hash_update(hmac_sha256_obj, "1234567890")
-        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
-        log.info("hmac_sha256_stream", hmac_sha256_result)
-        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
 
-        -- SHA512
-        local sha512_obj = crypto.hash_init("SHA512")
-        if sha512_obj then
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            crypto.hash_update(sha512_obj, "1234567890")
-            local sha512_result = crypto.hash_finish(sha512_obj)
-            log.info("sha512_stream", sha512_result)
-            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
-        end
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
 
-        -- HMAC_SHA512
-        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
-        if hmac_sha512_obj then
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            crypto.hash_update(hmac_sha512_obj, "1234567890")
-            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
-            log.info("hmac_sha512_stream", hmac_sha512_result)
-            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
-        end
-    else
-        log.info("crypto", "当前固件不支持crypto.hash_init")
-    end
 
-    log.info("crc7测试")
-    if crypto.crc7 then
-        local result = crypto.crc7(string.char(0xAA), 0xE5, 0x00)
-        log.info("crc7测试", result, string.format("%02X", result))
-    else
-        log.info("crypto", "当前固件不支持crypto.crc7")
-    end
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
 
-    log.info("crypto", "ALL Done")
-    sys.wait(100000)
-end)
+-- 加载crypto_app应用功能模块
+require "crypto_app"
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句
 sys.run()
--- sys.run()之后后面不要加任何语句!!!!!
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 149 - 0
module/Air8000/demo/crypto/readme.md

@@ -0,0 +1,149 @@
+## 功能模块介绍
+
+1、main.lua:主程序入口;
+
+2、crypto_app.lua:演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+3、logo.jpg:待加密文件
+
+## 演示功能概述
+
+1、创建一个task;
+
+2、演示有关加解密的各种 API 的功能;
+
+
+## 演示硬件环境
+
+![](https://docs.openluat.com/luatos_lesson/image/Evh1bVjatoG1rCxhrdpc9ny7nVf.png)
+
+1、Air8000核心板一块
+
+2、TYPE-C USB数据线一根
+
+4、Air8000核心板和数据线的硬件接线方式为
+
+- Air8000核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
+- 核心板正面的 供电/充电 拨动开关 拨到供电一端;
+- 核心板背面的 USB ON/USB OFF 拨动开关 拨到USB ON一端;
+
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air8000/luatos/common/download/)
+
+2、[Air8000 最新版本的内核固件](https://docs.openluat.com/air8000/luatos/firmware/)
+
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools烧录内核固件和demo脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、出现类似于下面的日志,就表示运行成功:
+
+``` lua
+[2025-10-16 15:00:32.204][000000000.203] I/user.main luatos_crypto_app 001.000.000
+[2025-10-16 15:00:32.794][000000001.212] I/user.md5 900150983CD24FB0D6963F7D28E17F72
+[2025-10-16 15:00:32.794][000000001.213] I/user.hmac_md5 416478FC0ACE1C4AB37F85F4F86A16B1
+[2025-10-16 15:00:32.794][000000001.213] I/user.sha1 A9993E364706816ABA3E25717850C26C9CD0D89D
+[2025-10-16 15:00:32.805][000000001.214] I/user.hmac_sha1 DAE54822C0DAF6C115C97B0AD62C7BCBE9D5E6FC
+[2025-10-16 15:00:32.810][000000001.214] I/user.sha256 BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
+[2025-10-16 15:00:32.814][000000001.215] I/user.hmac_sha256 86055184805B4A466A7BE398FF4A7159F9055EA7EEF339FC94DCEC6F165898BA
+[2025-10-16 15:00:32.814][000000001.216] I/user.sha512 DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F
+[2025-10-16 15:00:32.826][000000001.217] I/user.hmac_sha512 0F92B9AC88949E0BF7C9F1E6F9901BAB8EDFDC9E561DFDE428BC4339961A0569AD01B44343AA56E439949655D15C4D28492D459E75015489920243F3C9986F2A
+[2025-10-16 15:00:32.834][000000001.217] D/crypto zero padding
+[2025-10-16 15:00:32.842][000000001.218] I/user.AES aes-128-ecb 013EEA6EBACCBD7AD990FAEF75FB99C4 32
+[2025-10-16 15:00:32.844][000000001.218] I/user.AES aes-128-ecb 023001
+[2025-10-16 15:00:32.844][000000001.219] I/user.AES aes-128-ecb A37DE67837A1A3006E47A7BC25AA0ECC030B4E058E1972FE5B257FD8C3436142 64
+[2025-10-16 15:00:32.858][000000001.219] I/user.AES aes-128-cbc 26D98EA512AE92BC487536B83F2BE99B467649A9700338F4B4FF75AA2654DD2C 64
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-ecb 12345678901234 > 123456
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-cbc 12345678901234 > 123456
+[2025-10-16 15:00:32.874][000000001.220] I/user.mem 2376584 49564 58880
+[2025-10-16 15:00:32.884][000000001.221] I/user.des 486CB8B81CACCDB7 16
+[2025-10-16 15:00:32.889][000000001.221] I/user.des abcdefg
+[2025-10-16 15:00:32.894][000000001.222] I/user.3des 14619F067B425995D0CD975B85491D98 32
+[2025-10-16 15:00:32.894][000000001.223] I/user.3des abcdefg!!--ZZSS
+[2025-10-16 15:00:32.894][000000001.223] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.914][000000001.224] I/user.crc32 21438764
+[2025-10-16 15:00:32.914][000000001.225] I/user.crc32 21438764
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 197
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 243
+[2025-10-16 15:00:32.937][000000001.226] I/user.crc7 50 32
+[2025-10-16 15:00:32.937][000000001.226] I/user.随机数测试
+[2025-10-16 15:00:32.944][000000001.334] I/user.crypto 真随机数 -939521674 5
+[2025-10-16 15:00:33.016][000000001.434] I/user.crypto 真随机数 -1872085296 5
+[2025-10-16 15:00:33.111][000000001.534] I/user.crypto 真随机数 517455164 5
+[2025-10-16 15:00:33.223][000000001.634] I/user.crypto 真随机数 657132096 5
+[2025-10-16 15:00:33.311][000000001.734] I/user.crypto 真随机数 -1080191914 5
+[2025-10-16 15:00:33.421][000000001.834] I/user.crypto 真随机数 -833578535 5
+[2025-10-16 15:00:33.532][000000001.942] I/user.crypto 真随机数 420499958 5
+[2025-10-16 15:00:33.626][000000002.042] I/user.crypto 真随机数 1233025030 5
+[2025-10-16 15:00:33.720][000000002.142] I/user.crypto 真随机数 2138275442 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.crypto 真随机数 182791818 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.totp的密钥
+[2025-10-16 15:00:33.830][000000002.243] I/user.totp 522113 19 29 37
+[2025-10-16 15:00:33.830][000000002.244] I/user.totp 964300 19 30 7
+[2025-10-16 15:00:33.830][000000002.245] I/user.totp 987714 19 30 37
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 037499 19 31 7
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 699697 19 31 37
+[2025-10-16 15:00:33.830][000000002.247] I/user.totp 548191 19 32 7
+[2025-10-16 15:00:33.845][000000002.248] I/user.totp 747517 19 32 37
+[2025-10-16 15:00:33.845][000000002.249] I/user.totp 243319 19 33 7
+[2025-10-16 15:00:33.861][000000002.249] I/user.totp 147474 19 33 37
+[2025-10-16 15:00:33.877][000000002.250] I/user.totp 039992 19 34 7
+[2025-10-16 15:00:33.877][000000002.251] I/user.totp 628512 19 34 37
+[2025-10-16 15:00:33.877][000000002.252] I/user.totp 529018 19 35 7
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 994006 19 35 37
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 851359 19 36 7
+[2025-10-16 15:00:33.907][000000002.254] I/user.totp 943237 19 36 37
+[2025-10-16 15:00:33.908][000000002.255] I/user.totp 410702 19 37 7
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 082993 19 37 37
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 193281 19 38 7
+[2025-10-16 15:00:33.908][000000002.257] I/user.totp 781573 19 38 37
+[2025-10-16 15:00:33.924][000000002.258] I/user.totp 243288 19 39 7
+[2025-10-16 15:00:33.924][000000002.258] I/user.base64 encode MTIz
+[2025-10-16 15:00:33.924][000000002.259] I/user.base64 decode MTIz 123
+[2025-10-16 15:00:33.924][000000002.260] I/user.cipher list ["AES-128-ECB","AES-192-ECB","AES-256-ECB","AES-128-CBC","AES-192-CBC","AES-256-CBC","AES-128-CTR","AES-192-CTR","AES-256-CTR","AES-128-GCM","AES-192-GCM","AES-256-GCM","AES-128-CCM","AES-192-CCM","AES-256-CCM","DES-ECB","DES-EDE-ECB","DES-EDE3-ECB","DES-CBC","DES-EDE-CBC","DES-EDE3-CBC"]
+[2025-10-16 15:00:33.939][000000002.266] I/user.cipher suites 
+[2025-10-16 15:00:33.939][000000002.266] ["TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CCM","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8","TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CCM","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8","TLS-RSA-WITH-AES-256-GCM-SHA384","TLS-RSA-WITH-AES-256-CCM","TLS-RSA-WITH-AES-256-CBC-SHA256","TLS-RSA-WITH-AES-256-CBC-SHA","TLS-RSA-WITH-AES-256-CCM-8","TLS-RSA-WITH-AES-128-GCM-SHA256","TLS-RSA-WITH-AES-128-CCM","TLS-RSA-WITH-AES-128-CBC-SHA256","TLS-RSA-WITH-AES-128-CBC-SHA","TLS-RSA-WITH-AES-128-CCM-8","TLS-RSA-PSK-WITH-AES-256-GCM-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA","TLS-RSA-PSK-WITH-AES-128-GCM-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-256-GCM-SHA384","TLS-PSK-WITH-AES-256-CCM","TLS-PSK-WITH-AES-256-CBC-SHA384","TLS-PSK-WITH-AES-256-CBC-SHA","TLS-PSK-WITH-AES-256-CCM-8","TLS-PSK-WITH-AES-128-GCM-SHA256","TLS-PSK-WITH-AES-128-CCM","TLS-PSK-WITH-AES-128-CBC-SHA256","TLS-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-128-CCM-8"]
+[2025-10-16 15:00:33.955][000000002.266] I/user.文件hash值测试
+[2025-10-16 15:00:33.955][000000002.269] I/user.md5 D364D04CCD734D2757B25F3216CC431B
+[2025-10-16 15:00:33.955][000000002.273] I/user.sha1 04DA64874D415B1FB9CDD2E89927397D8F48C441
+[2025-10-16 15:00:33.955][000000002.284] I/user.sha256 0C601722B4BD2BC1A76BC3701F4EB646F5119C31702852978C326CD8D7C9212C
+[2025-10-16 15:00:33.955][000000002.287] I/user.hmac_md5 B5F5A687DB904DB67D3311899932DD61
+[2025-10-16 15:00:33.955][000000002.290] I/user.hmac_sha1 2A0B55C290D54ADF2F185EAE460254D267C7CE1F
+[2025-10-16 15:00:33.971][000000002.301] I/user.hmac_sha256 6E443C84D4D7A4721A9A195EB9038EDCFA8A8F60A3F1E8A0090B57B3BAB4942E
+[2025-10-16 15:00:33.971][000000002.301] I/user.md5
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha1
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha256
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_md5
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_sha1
+[2025-10-16 15:00:33.971][000000002.304] I/user.hmac_sha256
+[2025-10-16 15:00:33.971][000000002.304] I/user.流式hash测试
+[2025-10-16 15:00:33.986][000000002.304] I/user.md5_stream F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.305] I/user.md5 F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5_stream 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1_stream C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1 C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1_stream 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256_stream A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256 A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.310] I/user.hmac_sha256_stream EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.hmac_sha256 EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.sha512_stream 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.312] I/user.sha512 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.313] I/user.hmac_sha512_stream 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.314] I/user.hmac_sha512 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum OK 04 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum 357E E4 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.crypto ALL Done
+
+```

+ 282 - 0
module/Air8101/demo/crypto/crypto_app.lua

@@ -0,0 +1,282 @@
+--[[
+@module  crypto_app
+@summary crypto_app应用功能模块 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本文件为crypto_app应用功能模块,核心业务逻辑为:
+1、演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+本文件没有对外接口,直接在main.lua中require "crypto_app"就可以加载运行;
+]]
+
+--加密运算主函数
+local function crypto_task_func()
+
+    -- MD5/哈希MD5,输出结果已经hex编码
+    log.info("md5", crypto.md5("abc"))
+    log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
+
+    -- SHA1/哈希SHA1,输出结果已经hex编码
+    log.info("sha1", crypto.sha1("abc"))
+    log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
+
+    -- SHA256/哈希SHA256,输出结果已经hex编码
+    log.info("sha256", crypto.sha256("abc"))
+    log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
+
+    -- SHA512/哈希SHA512,输出结果已经hex编码
+    log.info("sha512", crypto.sha512("abc"))
+    log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
+
+	-- AES加密, 未经Hex编码. AES-128-ECB 算法 对称加密,对齐方式:"ZERO"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "ZERO", "023001", "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+	local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "ZERO", data_encrypt, "HZBIT@WLW/YSBKEY")
+	log.info("AES", "aes-128-ecb", data_decrypt)
+
+    -- AES加密, 未经Hex编码. AES-128-ECB/CBC 算法 对称加密,对齐方式:"PKCS7"
+    local data_encrypt = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "12345678901234 > 123456", "1234567890123456")
+    local data2_encrypt = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "12345678901234 > 123456", "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_encrypt:toHex())
+    log.info("AES", "aes-128-cbc", data2_encrypt:toHex())
+
+    -- AES解密, 未经Hex编码, AES-128-ECB/CBC 算法 对称解密,,对齐方式:"PKCS7"
+    local data_decrypt = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data_encrypt, "1234567890123456")
+    local data2_decrypt = crypto.cipher_decrypt("AES-128-CBC", "PKCS7", data2_encrypt, "1234567890123456", "1234567890666666")
+    log.info("AES", "aes-128-ecb", data_decrypt)
+    log.info("AES", "aes-128-cbc", data2_decrypt)
+    log.info("mem", rtos.meminfo("sys"))
+
+    -- DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
+    if data1 then 
+        log.info("des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-ECB", "PKCS7", data1, "12345678")
+        log.info("des", data2)
+    else
+        log.info("des", "当前固件不支持DES/3DES")
+    end
+
+    -- 3DES-ECB 加解密
+    local data1 = crypto.cipher_encrypt("DES-EDE3-ECB", "PKCS7", "abcdefg!!--ZZSS", "123456781234567812345678")
+    if data1 then 
+        log.info("3des", data1:toHex())
+        local data2 = crypto.cipher_decrypt("DES-EDE3-ECB", "PKCS7", data1, "123456781234567812345678")
+        log.info("3des", data2)
+    else
+        log.info("3des", "当前固件不支持DES/3DES")
+    end
+  
+    -- 计算CRC16
+    local originStr = "123456sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc16 = crypto.crc16("MODBUS",originStr)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC16 modbus
+    local crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234")
+    log.info("crc16", crc16)
+    crc16 = crypto.crc16_modbus("123456sdfdsfdsfdsffdsfdsfsdfs1234", 0xFFFF)
+    log.info("crc16", crc16)
+    
+    -- 计算CRC32
+    local data = "123456sdfdsfdsfdsffdsfdsfsdfs1234" 
+    local crc32 = crypto.crc32(data)
+    log.info("crc32", crc32) --21438764
+    -- start和poly可选, 是 2025.4.14 新增的参数
+    local crc32 = crypto.crc32(data, 0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF) --等同于crypto.crc32(data)
+    log.info("crc32", crc32)
+
+    -- 计算CRC8
+    local data= "sdfdsfdsfdsffdsfdsfsdfs1234"
+    local crc8 = crypto.crc8(data)
+    log.info("crc8", crc8)
+    local crc8 = crypto.crc8(data, 0x31, 0xff, false)
+    log.info("crc8", crc8)  
+        
+    -- 计算CRC7
+    if crypto.crc7 then
+        local result = crypto.crc7("abc", 0xE5, 0x00)
+        log.info("crc7", result, string.format("%02X", result))  --50 32
+    else
+        log.info("crypto", "当前固件不支持crypto.crc7")
+    end
+    
+    log.info("随机数测试")
+    for i=1, 10 do
+        sys.wait(100)
+        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
+        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
+        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
+    end
+
+    -- totp的密钥
+    log.info("totp的密钥")
+    local secret = "VK54ZXPO74ISEM2E"
+    --写死时间戳用来测试
+    local ts = 1646796576
+    --生成十分钟的动态码验证下
+    for i=1,600,30 do
+        local r = crypto.totp(secret,ts+i)
+        local time = os.date("*t",ts+i + 8*3600)--东八区
+        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
+    end
+    
+    --将数据进行base64编码
+    -- 本函数与 string.toBase64 是同一个
+    local bdata = crypto.base64_encode("123")
+    log.info("base64", "encode", bdata)
+    
+    --将数据进行base64解码
+    -- 本函数与 string.fromBase64 是同一个
+    local data = crypto.base64_decode("MTIz")
+    log.info("base64", "decode", bdata, data)--123    
+
+    -- 打印所有支持的cipher
+    if crypto.cipher_list then
+        log.info("cipher", "list", json.encode(crypto.cipher_list()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_list")
+    end
+    -- 打印所有支持的cipher suites
+    if crypto.cipher_suites then
+        log.info("cipher", "suites", json.encode(crypto.cipher_suites()))
+    else
+        log.info("cipher", "当前固件不支持crypto.cipher_suites")
+    end
+    
+    -- 计算文件的hash值(md5/sha1/sha256及hmac形式)
+    log.info("文件hash值测试")
+    if crypto.md_file then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
+        log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
+        log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
+        log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
+    else
+        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
+    end
+    
+    --计算数据的hash值(md5/sha1/sha256及hmac形式)
+    if crypto.md then
+        -- 无hmac的hash值
+        log.info("md5", crypto.md("MD5", "1234567890"))
+        log.info("sha1", crypto.md("SHA1", "1234567890"))
+        log.info("sha256", crypto.md("SHA256", "1234567890"))
+        
+        -- 带hmac的hash值
+        log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
+        log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
+        log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
+    else
+        log.info("数据hash值测试", "当前固件不支持crypto.md")    
+    end
+    
+    -- 流式hash测试
+    log.info("流式hash测试")
+    if crypto.hash_init then
+        -- MD5
+        local md5_obj = crypto.hash_init("MD5")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        crypto.hash_update(md5_obj, "1234567890")
+        local md5_result = crypto.hash_finish(md5_obj)
+        log.info("md5_stream", md5_result)
+        log.info("md5", crypto.md5("1234567890123456789012345678901234567890"))
+
+        -- HMAC_MD5
+        local hmac_md5_obj = crypto.hash_init("MD5", "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        crypto.hash_update(hmac_md5_obj, "1234567890")
+        local hmac_md5_result = crypto.hash_finish(hmac_md5_obj)
+        log.info("hmac_md5_stream", hmac_md5_result)
+        log.info("hmac_md5", crypto.hmac_md5("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA1
+        local sha1_obj = crypto.hash_init("SHA1")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        crypto.hash_update(sha1_obj, "1234567890")
+        local sha1_result = crypto.hash_finish(sha1_obj)
+        log.info("sha1_stream", sha1_result)
+        log.info("sha1", crypto.sha1("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA1
+        local hmac_sha1_obj = crypto.hash_init("SHA1", "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        crypto.hash_update(hmac_sha1_obj, "1234567890")
+        local hmac_sha1_result = crypto.hash_finish(hmac_sha1_obj)
+        log.info("hmac_sha1_stream", hmac_sha1_result)
+        log.info("hmac_sha1", crypto.hmac_sha1("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA256
+        local sha256_obj = crypto.hash_init("SHA256")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        crypto.hash_update(sha256_obj, "1234567890")
+        local sha256_result = crypto.hash_finish(sha256_obj)
+        log.info("sha256_stream", sha256_result)
+        log.info("sha256", crypto.sha256("1234567890123456789012345678901234567890"))
+
+        -- HMAC_SHA256
+        local hmac_sha256_obj = crypto.hash_init("SHA256", "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        crypto.hash_update(hmac_sha256_obj, "1234567890")
+        local hmac_sha256_result = crypto.hash_finish(hmac_sha256_obj)
+        log.info("hmac_sha256_stream", hmac_sha256_result)
+        log.info("hmac_sha256", crypto.hmac_sha256("1234567890123456789012345678901234567890", "1234567890"))
+
+        -- SHA512
+        local sha512_obj = crypto.hash_init("SHA512")
+        if sha512_obj then
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            crypto.hash_update(sha512_obj, "1234567890")
+            local sha512_result = crypto.hash_finish(sha512_obj)
+            log.info("sha512_stream", sha512_result)
+            log.info("sha512", crypto.sha512("1234567890123456789012345678901234567890"))
+        end
+
+        -- HMAC_SHA512
+        local hmac_sha512_obj = crypto.hash_init("SHA512", "1234567890")
+        if hmac_sha512_obj then
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            crypto.hash_update(hmac_sha512_obj, "1234567890")
+            local hmac_sha512_result = crypto.hash_finish(hmac_sha512_obj)
+            log.info("hmac_sha512_stream", hmac_sha512_result)
+            log.info("hmac_sha512", crypto.hmac_sha512("1234567890123456789012345678901234567890", "1234567890"))
+        end
+    else
+        log.info("crypto", "当前固件不支持crypto.hash_init")
+    end
+   
+    if crypto.checksum then
+        log.info("checksum", "OK", string.char(crypto.checksum("OK")):toHex())
+        log.info("checksum", "357E", string.char(crypto.checksum("357E", 1)):toHex())
+    else
+        log.info("checksum", "当前固件不支持crypto.checksum")
+    end    
+
+    log.info("crypto", "ALL Done")
+    sys.wait(100000)
+end    
+
+--创建一个task,并且运行task的主函数crypto_task_func
+sys.taskInit(crypto_task_func)

BIN
module/Air8101/demo/crypto/logo.jpg


+ 0 - 18
module/Air8101/demo/crypto/luadb/luatos_uploadFile.txt

@@ -1,18 +0,0 @@
-1 208
-2 416
-3 624
-4 832
-5 1040
-
-6.84S + 5ms 开始
-
-11100000 6.87S  00000111
-00111010 6.9S   01011100
-6.91S
-11111000 6.93   00011111
-6.94
-01101100 6.96   00110110
-
-
-6*2
-*255

+ 52 - 498
module/Air8101/demo/crypto/main.lua

@@ -1,517 +1,71 @@
-
--- LuaTools需要PROJECT和VERSION这两个信息
-PROJECT = "cryptodemo"
-VERSION = "1.0.0"
-
--- 定义串行口及其波特率
-local uart_id = 1
-local uart_baud = 115200
--- 输出项目目名称及版本号
-log.info("main", PROJECT, VERSION)
-
-
---初始化
---[[uart.setup(
-    uartid,--串口id
-    115200,--波特率
-    8,--数据位
-    1--停止位
-)
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
+@version 1.0
+@date    2025.10.15
+@author  沈园园
+@usage
+本demo演示的核心功能为:
+演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和
+更多说明参考本目录下的readme.md文件
 ]]
 
---配置并且打开串口
-uart.setup(uart_id,uart_baud,8,1)
-
---注册串口的数据发送通知函数
-uart.on(uart_id,"receive",function() 
-    log.info("uart "," uart received ")
-    sys.publish("UART_RECEIVE") 
-end)
---uart.on(uart_id,"sent",writeOK)
-
---将数据写入串行口
-function write_pack(s)
-    --log.info("write_pack", s )
-    uart.write(uart_id,s.."\r\n")
-end
-
--- 参数说明
--- cry_name 具体的加密方法,如md5。
--- func 具体的执行函数如 crypto.md5。
--- buff 串行口接收到的数据
-function  crypto_todo( cry_name, func ,buff )
-    local   cry_start,cry_end = buff:find( cry_name )
-    
-    if cry_start ~= nil then
-    -- 取得尾部字符
-        items_data = buff:sub( cry_end+1 , -1 )
-        -- 为了简便起见,就不通过串行口发送密钥了,毕竟这不是一个串行口数据解析的演示
-        log.info( cry_name, func( items_data ) )
-        write_pack( cry_name.." <==> code [ "..func( items_data ).." ]" )
-    end
-end
-
--- 参数说明
--- cry_name 具体的加密方法,如md5。
--- func 具体的执行函数如 crypto.md5。
--- buff 串行口接收到的数据
-function  crypto_todo_hmac( cry_name, func ,buff )
-    local password
-    local cry_start,cry_end = buff:find( "password" )
-    if cry_start == nil then
-        password = "1234567890"
-    else
-        password = buff:sub( cry_end+1 , -1 )
-        buff = buff:sub( 1, cry_start-1)
-        --log.info("password ",password,buff)
-    end
-    cry_start,cry_end = buff:find( cry_name )
-   
-    if cry_start ~= nil then
-    -- 取得尾部字符
-        items_data = buff:sub( cry_end+1 , -1 )
-        -- 为了简便起见,就不通过串行口发送密钥了,毕竟这不是一个串行口数据解析的演示
-        log.info( cry_name, func( items_data , password ) )
-        write_pack( cry_name.." <==> password [ "..password.." ]   code [ "..func( items_data , password ).." ]\r\n" )
-    end
-end
-
-function todo_cihper_ecb(name_full ,padding , items_data , password)
-    log.info("-------------------------" , name_full , padding , items_data , password )
-
-    data_encrypt = crypto.cipher_encrypt( name_full , padding , items_data , password )
-
-    log.info("-------------------------")
-    if data_encrypt ~= nil then
-        write_pack( name_full.." encrypt <==> ["..padding.."] password [ "..password.." ]   code [ "..data_encrypt.." ]\r\n" )
-        write_pack( name_full.." encrypt <==> ["..padding.."] password [ "..password.." ]   code_HEX [ "..data_encrypt:toHex().." ]\r\n" )
-        
-        data_encrypt = crypto.cipher_decrypt(name_full, padding, data_encrypt, password )
-    
-        write_pack( name_full.." decrypt <==> ["..padding.."] password [ "..password.." ]   code [ "..data_encrypt.." ]\r\n" )
-    else
-        write_pack( name_full.." encrypt <==> ["..padding.."] password [ "..password.." ]   code [ data_encrypt error ]\r\n" )
-    end
-end
-
-function todo_cihper_not_ecb(name_full , padding , items_data , password , iv)
-    log.info("-------------------------" , name_full ,padding , items_data , password , iv )
-    data_encrypt = crypto.cipher_encrypt( name_full , padding , items_data , password , iv ) 
-    log.info("-------------------------")
-    
-    if data_encrypt ~= nil then
-        -- 输出原码与输出HEX各一组,方便比较
-        write_pack( name_full.." encrypt <==> ["..padding.."] password [ "..password.." ] IV [ "..iv.." ]  code [ "..data_encrypt.." ]\r\n" )
-        write_pack( name_full.." encrypt <==> ["..padding.."] password [ "..password.." ] IV [ "..iv.." ]  code_HEX [ "..data_encrypt:toHex().." ]\r\n" )
-        data_encrypt = crypto.cipher_decrypt(name_full, padding, data_encrypt, password,iv) 
-    
-        write_pack( name_full.." decrypt <==> ["..padding.."] password [ "..password.." ]   code [ "..data_encrypt.." ]\r\n" )
-    else
-        write_pack( name_full.." encrypt <==> ["..padding.."] password [ "..password.." ] IV [ "..iv.." ]  code [ data_encrypt error ]\r\n" ) 
-    end
-end
--- AES 加密解密
--- cryname 加密名称+对齐方式+加密字符串
-function  crypto_todo_cipher( cry_name , padding , buff )
-    local password
-    local cry_start,cry_end = buff:find( "password" )
-    if cry_start == nil then
-        password = ""
-    else
-        password = buff:sub( cry_end+1 , -1 )
-        buff = buff:sub( 1,cry_start-1)
-        --log.info("1 password ",password,buff)
-    end
-
-    -- 匹配查找
-    cry_start,cry_end = buff:find( cry_name )  
-    -- 找到加密名称
-    if cry_start ~= nil then
-        -- 取得加密方法名称
-        local name_full = buff:sub(cry_start,cry_end)
-        log.info( "<----->",name_full )
-        -- 取得尾部字符
-        cry_start,cry_end = buff:find( padding )
-        -- 找到对齐方式
-        if cry_start ~= nil then
-            local data_encrypt
-            local iv
-            local password_len
-
-            name_full = name_full:upper()
-            padding = padding:upper()
-
-                -- 取得加密数据
-            items_data = buff:sub( cry_end+1 , -1 )
-
-            --[[
-            参数
-            name_full         算法名称, 例如 AES-128-ECB/AES-128-CBC, 可查阅crypto.cipher_list()
-            padding           对齐方式, 支持PKCS7/ZERO/ONE_AND_ZEROS/ZEROS_AND_LEN/NONE
-            items_data        需要加密的数据
-            HZBIT@WLW/YSBKEY  密钥,需要对应算法的密钥长度
-            IV                非ECB算法需要]]
-
-            cry_end = buff:find("des")
-            -- 进行DES 加密 处理
-            if cry_end ~= nil then
-                if password == "" then
-                    cry_start = buff:find( "ede3" )
-                    if cry_start ~= nil  then
-                        password = "123456781234567812345678"
-                    else
-                        password = "12345678"
-                    end
-                end
-                cry_start,cry_end = buff:find( "ecb" )
-                if cry_start ~= nil then
-                    -- 应当也是有密码长度规范的,但为此处不再进行判定处理。
-                    -- 如果导致出错,请注意是不是密码长度引起。
-                    todo_cihper_ecb( name_full , padding , items_data , password )  
-                else
-                    todo_cihper_not_ecb( name_full , padding , items_data , password , "12345678")  
-                end
 
-            else
-                -- 进行字符串匹配 取得开始位置及加密长度 可以是 128、192、256等值
-                -- 一般来说,密钥的长度就是加密长度,比如128,就表示16个字节长度
-                cry_start,cry_end,password_len = buff:find( "aes[-](%d+)[-]%a%a%a" )
-
-                if password_len == nil then
-                    password_len = "0"
-                end
-
-                --如果密码为空,则截取合适的长度字串作为密码
-                if password == "" then
-                    password = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                    password = password:sub(1, tonumber(password_len)/8 )
-                end
-                if  tonumber(password_len) / 8 == password:len() then
-                    log.info( "-----","password ok", password , name_full , padding)
-                    cry_start = buff:find( "ecd" )                    
-                    if cry_start ~= nil then
-                        todo_cihper_ecb( name_full , padding , items_data , password )  
-                    else
-                        todo_cihper_not_ecb( name_full , padding , items_data , password , "1234567890666666" )  
-                    end                    
-                else
-                    log.info("-----","password error")
-                    write_pack( "password length error ==="..password_len.."\r\n" )
-                end
-            end
-        end
-    end
-end
-
--- 文件测试
-function todo_md_file(buff)
-    local password
-    local cry_start,cry_end = buff:find( "password" )
-    if cry_start == nil then
-        password = ""
-    else
-        password = buff:sub( cry_end+1 , -1 )
-        buff = buff:sub( 1, cry_start-1)
-        log.info("md_file password ",password,buff)
-    end
-
-    log.info("文件hash值测试")
-    if crypto.md_file then
-        local md_file =crypto.md_file( "MD5" , "/luadb/luatos_uploadFile.txt" )
-        write_pack( "md_file encrypt MD5 <==> code [ "..md_file.." ]\r\n" )
-        
-        md_file =crypto.md_file( "SHA1" , "/luadb/luatos_uploadFile.txt" )
-        write_pack( "md_file encrypt SHA1 <==> code [ "..md_file.." ]\r\n" )
-        
-        md_file =crypto.md_file( "SHA256" , "/luadb/luatos_uploadFile.txt" )
-        write_pack( "md_file encrypt SHA256 <==> code [ "..md_file.." ]\r\n" )
-     
-        md_file =crypto.md_file("MD5" , "/luadb/luatos_uploadFile.txt" , password )
-        write_pack( "md_file encrypt hmac_md5 <==> password [ "..password.." ] code [ "..md_file.." ]\r\n" )
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "luatos_crypto_app"
+VERSION = "001.000.000"
 
-        md_file =crypto.md_file("SHA1" , "/luadb/luatos_uploadFile.txt" , password )
-        write_pack( "md_file encrypt hmac_sha1 <==> password [ "..password.." ] code [ "..md_file.." ]\r\n" )
 
-        md_file =crypto.md_file("SHA256" , "/luadb/luatos_uploadFile.txt" , password )
-        write_pack( "md_file encrypt hmac_sha256 <==> password [ "..password.." ] code [ "..md_file.." ]\r\n" )
-    else
-        log.info("文件hash值测试", "当前固件不支持crypto.md_file")
-    end
-end
-
-function todo_checksum(buff)
-    local cry_start,cry_end = buff:find("checksum")
-    if cry_start ~= nil then
-        local cry_text = buff:sub(cry_end+1,-1)
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
 
-        if crypto.checksum then
-            write_pack( "checksum encrypt <==>text [ "..cry_text.." ]  code [ "..string.char(crypto.checksum( cry_text ) ):toHex().." ]\r\n" )
-            write_pack( "checksum encrypt <==>text [ "..cry_text.." ]  code [ "..string.char(crypto.checksum( cry_text , 1 ) ):toHex().." ]\r\n" )
-        else
-            log.info("checksum", "当前固件不支持crypto.checksum")
-        end
-    end
-end
 
--- 流数据校验演示
-function toto_hash_init( cry_name , method , buff )
-    local password
-    local cry_start,cry_end = buff:find("password")
-    if cry_start ~= nil then
-        --  读取密码
-        password = buff:sub(cry_end+1,-1)
-        buff = buff:sub( 1 , cry_start-1 );
-    else
-        password = ""
-    end
-     
-    -- 本过程不再对拼接后的完整数据进行校验,如果有需要,请使用单独的MD5或SHA1加密方法进行验证即可。
-    -- 比如 MD5 的流校验操作,假如使用的文本是 "123456456",则验证可通过串行口发送
-    -- md5123456456123456456123456456123456456 来验证。这是因为演示就是连续操作四次发送的文本,来
-    -- 模拟流操作的过程,以演示累积的加密处理方法。
-    cry_start,cry_end = buff:find( cry_name..method )
-    if cry_start ~= nil then
-       local cry_text = buff:sub(cry_end+1,-1)
-       
-       log.info("md5-----", cry_text, password , method)
-       if password == ""  then
-            -- 转化为大写
-            local md5_obj = crypto.hash_init( method:upper() )
-            crypto.hash_update(md5_obj, cry_text)
-            crypto.hash_update(md5_obj, cry_text)
-            crypto.hash_update(md5_obj, cry_text)
-            crypto.hash_update(md5_obj, cry_text)
-            local md5_result = crypto.hash_finish(md5_obj)
-            
-            write_pack( "stream encrypt <==>name [ "..cry_name.." ] method [ "..method.." ] text [ "..cry_text.." ] result [ "..md5_result.." ]\r\n" )
-            log.info("md5_stream", md5_result)
-       else
-            local md5_obj = crypto.hash_init( method:upper() , password )
-            crypto.hash_update(md5_obj, cry_text , password )
-            crypto.hash_update(md5_obj, cry_text , password )
-            crypto.hash_update(md5_obj, cry_text , password )
-            crypto.hash_update(md5_obj, cry_text , password )
-            local md5_result = crypto.hash_finish(md5_obj)
-            write_pack( "stream encrypt <==>password ["..password.."] name [ "..cry_name.." ] method [ hmac_"..method.." ] text [ "..cry_text.." ] result [ "..md5_result.." ]\r\n" )
-            log.info("md5_stream", md5_result)
-       end
-    end
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
+if wdt then
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
 end
 
-sys.taskInit(function()
-
-    -- 数据接收缓冲区
-    -- 使用缓冲区的目的是为了接收全部数据后再分析
-    local cacheData = ""
-    
-    local data2_encrypt = crypto.cipher_encrypt("DES-ECB", "PKCS7", "abcdefg", "12345678")
-
-    sys.wait(1000)
-    while true do
-
-        ::continue::
-        local s = uart.read(uart_id,1024)
-
-        if s == "" then
-            if cacheData == "" then
-                sys.waitUntil("UART_RECEIVE" , 500)
-                goto continue
-            end
-
-            -- 定义变量
-            local cry_str
-            local items_data
-            local cry_start,cry_end
-
-            -- 测试一下串行口
-            cry_start,cry_end = cacheData:find( "uart" )
-            if cry_start ~= nil then
-                write_pack( "test uart[baud=115200,8,0,1]\r\n" )
-            end
-
-            cry_start,cry_end = cacheData:find( "md_file" )
-            if cry_start ~= nil then
-                todo_md_file( cacheData ) 
-            end
-
-            --校验和
-            todo_checksum( cacheData )
-
-            cry_start,cry_end = cacheData:find( "list" )
-            if cry_start ~= nil then
-                -- 打印所有支持的cipher
-                if crypto.cipher_list then
-                    log.info("cipher", "list", json.encode(crypto.cipher_list()))
-                    --write_pack("cipher list [ " json.encode(crypto.cipher_list()).." ]" )
-                else
-                    log.info("cipher", "当前固件不支持crypto.cipher_list")
-                end
-            end
-
-            cry_start,cry_end = cacheData:find( "suites" )
-            if cry_start ~= nil then
-                -- 打印所有支持的cipher
-                if crypto.cipher_list then
-                    log.info("cipher", "suites", json.encode(crypto.cipher_suites()) )
-                    --write_pack("cipher suites [ " json.encode(crypto.cipher_suites()).." ]" )
-                else
-                    log.info( "cipher", "当前固件不支持crypto.cipher_suites" )
-                end
-            end
-
-            cry_start,cry_end = cacheData:find( "base64" )
-            if cry_start ~= nil then
-                -- 打印所有支持的cipher
-                if crypto.base64_encode then
-                    local in_text = cacheData:sub( cry_end + 1 , -1 );
-                    local bas_text = crypto.base64_encode( in_text )
-
-                    write_pack("cipher base64 encode data [ "..in_text.." ] code [ " .. bas_text .. " ]" )
-                    write_pack("cipher base64 decode data [ "..bas_text.." ] code [ " .. crypto.base64_decode( bas_text ).." ]" )
-                else
-                    log.info( "cipher", "当前固件不支持 base64 " )
-                end
-            end
-
-            cry_start,cry_end = cacheData:find( "base64_decode" )
-            if cry_start ~= nil then
-                -- 打印所有支持的cipher
-                if crypto.base64_encode then
-                    local in_text = cacheData:sub( cry_end + 1 , -1 );
-                    local bas_text = crypto.base64_decode( in_text )
-                    
-                    write_pack("cipher base64 decode data [ "..in_text.." ] code [ " .. bas_text .." ]" )
-                else
-                    log.info( "cipher", "当前固件不支持 base64 " )
-                end
-            end
-            -- 输出 MD5 编码
-            -- 当收到 hmac_md5 时,也会执行一次 md5,因只是作一个加密演示,作为演示
-            -- 不想做过于复杂的逻辑判断,因而就让其输出吧,关系也不大。
-            -- 下面遇到类似情况就不再作说明了,请知悉!
-            crypto_todo("md5" , crypto.md5 , cacheData )
-   
-            -- 输出hmac_md5
-            crypto_todo_hmac("hmac_md5" , crypto.hmac_md5 , cacheData )
-
-            -- 输出 sha1 编码
-            crypto_todo("sha1" , crypto.sha1 , cacheData )
-
-            -- 输出 hmac_sha1 编码
-            crypto_todo_hmac("hmac_sha1" , crypto.hmac_sha1 , cacheData )
-
-            -- 输出sha256
-            crypto_todo("sha256" , crypto.sha256 , cacheData )
-
-            -- 输出hmac_sha256
-            crypto_todo_hmac("hmac_sha256" , crypto.hmac_sha256 , cacheData )
-
-            -- 输出sha512
-            crypto_todo("sha512" , crypto.sha512 , cacheData )
-
-            -- 输出hmac_sha512
-            crypto_todo_hmac("hmac_sha512" , crypto.hmac_sha512 , cacheData )
-
-            toto_hash_init("hash_init" , "md5" , cacheData )
-            toto_hash_init("hash_init" , "sha1" , cacheData )
-            toto_hash_init("hash_init" , "sha256" , cacheData )
-            toto_hash_init("hash_init" , "sha512" , cacheData )
-
-            -- 对称加密算法
-            crypto_todo_cipher( "aes[-](%d+)[-]ecb", "zero",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]cbc", "zero",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ctr", "zero",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]xts", "zero",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]gcm", "zero",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ccm", "zero",cacheData)
-
-            crypto_todo_cipher( "aes[-](%d+)[-]ecb", "pkcs7",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]cbc", "pkcs7",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ctr", "pkcs7",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]xts", "pkcs7",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]gcm", "pkcs7",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ccm", "pkcs7",cacheData)
-
-            crypto_todo_cipher( "aes[-](%d+)[-]ecb", "one_and_zeros",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]cbc", "one_and_zeros",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ctr", "one_and_zeros",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]xts", "one_and_zeros",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]gcm", "one_and_zeros",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ccm", "one_and_zeros",cacheData)
-                        
-            crypto_todo_cipher( "aes[-](%d+)[-]ecb", "zeros_and_len",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]cbc", "zeros_and_len",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ctr", "zeros_and_len",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]xts", "zeros_and_len",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]gcm", "zeros_and_len",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ccm", "zeros_and_len",cacheData)
-
-            crypto_todo_cipher( "aes[-](%d+)[-]ecb", "none",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]cbc", "none",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ctr", "none",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]xts", "none",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]gcm", "none",cacheData)
-            crypto_todo_cipher( "aes[-](%d+)[-]ccm", "none",cacheData)
-
-            crypto_todo_cipher( "des[-]ecb" , "pkcs7", cacheData )
-            crypto_todo_cipher( "des[-]ede[-]ecb" , "pkcs7", cacheData )
-            crypto_todo_cipher( "des[-]ede3[-]ecb" , "pkcs7", cacheData )
-            crypto_todo_cipher( "des[-]cbc" , "pkcs7", cacheData )
-            crypto_todo_cipher( "des[-]ede[-]cbc" , "pkcs7", cacheData )
-            crypto_todo_cipher( "des[-]ede3[-]cbc" , "pkcs7", cacheData )
-
-            crypto_todo_cipher( "des[-]ecb" , "zero", cacheData )
-            crypto_todo_cipher( "des[-]ede[-]ecb" , "zero", cacheData )
-            crypto_todo_cipher( "des[-]ede3[-]ecb" , "zero", cacheData )
-            crypto_todo_cipher( "des[-]cbc" , "zero", cacheData )
-            crypto_todo_cipher( "des[-]ede[-]cbc" , "zero", cacheData )
-            crypto_todo_cipher( "des[-]ede3[-]cbc" , "zero", cacheData )
 
-            -- 处理完成后清空缓冲区
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
 
-            log.info("cacheData ",cacheData )
-            cacheData = ""
-        else
-            cacheData = cacheData..s
-        end 
-    end
 
-    --[[
-    log.info("随机数测试")
-    for i=1, 10 do
-        sys.wait(100)
-        log.info("crypto", "真随机数",string.unpack("I",crypto.trng(4)))
-        -- log.info("crypto", "伪随机数",math.random()) -- 输出的是浮点数,不推荐
-        -- log.info("crypto", "伪随机数",math.random(1, 65525)) -- 不推荐
-    end
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
 
-    -- totp的密钥
-    log.info("totp的密钥")
-    local secret = "VK54ZXPO74ISEM2E"
-    --写死时间戳用来测试
-    local ts = 1646796576
-    --生成十分钟的动态码验证下
-    for i=1,600,30 do
-        local r = crypto.totp(secret,ts+i)
-        local time = os.date("*t",ts+i + 8*3600)--东八区
-        log.info("totp", string.format("%06d" ,r),time.hour,time.min,time.sec)
-    end
 
-    log.info("crc7测试")
-    if crypto.crc7 then
-        local result = crypto.crc7(string.char(0xAA), 0xE5, 0x00)
-        log.info("crc7测试", result, string.format("%02X", result))
-    else
-        log.info("crypto", "当前固件不支持crypto.crc7")
-    end
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
 
-    log.info("crypto", "ALL Done")
-   --]]
-   sys.wait(100000)
-   
-end)
+-- 加载crypto_app应用功能模块
+require "crypto_app"
 
 -- 用户代码已结束---------------------------------------------
 -- 结尾总是这一句
 sys.run()
--- sys.run()之后后面不要加任何语句!!!!!
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 147 - 0
module/Air8101/demo/crypto/readme.md

@@ -0,0 +1,147 @@
+## 功能模块介绍
+
+1、main.lua:主程序入口;
+
+2、crypto_app.lua:演示有关加解密的各种 API 的功能包含MD5,SHA,哈希(MD5,SHA),AES/DEC/3DES,CRC,checksum校验和;
+
+3、logo.jpg:待加密文件
+
+## 演示功能概述
+
+1、创建一个task;
+
+2、演示有关加解密的各种 API 的功能;
+
+
+## 演示硬件环境
+
+![](https://docs.openluat.com/air8101/luatos/common/hwenv/image/Air8101.png)
+
+1、Air8101核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、Air8101核心板和数据线的硬件接线方式为
+
+- Air8000核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
+- Air8101核心板通过TYPE-C USB口供电(核心板背面的功耗测试开关拨到OFF一端);
+
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air8101/luatos/common/download/)
+
+2、[Air8101 最新版本的内核固件](https://docs.openluat.com/air8101/luatos/firmware/)
+
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、Luatools烧录内核固件和demo脚本代码
+
+3、烧录成功后,自动开机运行
+
+4、出现类似于下面的日志,就表示运行成功:
+
+``` lua
+[2025-10-16 15:00:32.204][000000000.203] I/user.main luatos_crypto_app 001.000.000
+[2025-10-16 15:00:32.794][000000001.212] I/user.md5 900150983CD24FB0D6963F7D28E17F72
+[2025-10-16 15:00:32.794][000000001.213] I/user.hmac_md5 416478FC0ACE1C4AB37F85F4F86A16B1
+[2025-10-16 15:00:32.794][000000001.213] I/user.sha1 A9993E364706816ABA3E25717850C26C9CD0D89D
+[2025-10-16 15:00:32.805][000000001.214] I/user.hmac_sha1 DAE54822C0DAF6C115C97B0AD62C7BCBE9D5E6FC
+[2025-10-16 15:00:32.810][000000001.214] I/user.sha256 BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD
+[2025-10-16 15:00:32.814][000000001.215] I/user.hmac_sha256 86055184805B4A466A7BE398FF4A7159F9055EA7EEF339FC94DCEC6F165898BA
+[2025-10-16 15:00:32.814][000000001.216] I/user.sha512 DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F
+[2025-10-16 15:00:32.826][000000001.217] I/user.hmac_sha512 0F92B9AC88949E0BF7C9F1E6F9901BAB8EDFDC9E561DFDE428BC4339961A0569AD01B44343AA56E439949655D15C4D28492D459E75015489920243F3C9986F2A
+[2025-10-16 15:00:32.834][000000001.217] D/crypto zero padding
+[2025-10-16 15:00:32.842][000000001.218] I/user.AES aes-128-ecb 013EEA6EBACCBD7AD990FAEF75FB99C4 32
+[2025-10-16 15:00:32.844][000000001.218] I/user.AES aes-128-ecb 023001
+[2025-10-16 15:00:32.844][000000001.219] I/user.AES aes-128-ecb A37DE67837A1A3006E47A7BC25AA0ECC030B4E058E1972FE5B257FD8C3436142 64
+[2025-10-16 15:00:32.858][000000001.219] I/user.AES aes-128-cbc 26D98EA512AE92BC487536B83F2BE99B467649A9700338F4B4FF75AA2654DD2C 64
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-ecb 12345678901234 > 123456
+[2025-10-16 15:00:32.864][000000001.220] I/user.AES aes-128-cbc 12345678901234 > 123456
+[2025-10-16 15:00:32.874][000000001.220] I/user.mem 2376584 49564 58880
+[2025-10-16 15:00:32.884][000000001.221] I/user.des 486CB8B81CACCDB7 16
+[2025-10-16 15:00:32.889][000000001.221] I/user.des abcdefg
+[2025-10-16 15:00:32.894][000000001.222] I/user.3des 14619F067B425995D0CD975B85491D98 32
+[2025-10-16 15:00:32.894][000000001.223] I/user.3des abcdefg!!--ZZSS
+[2025-10-16 15:00:32.894][000000001.223] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.905][000000001.224] I/user.crc16 54188
+[2025-10-16 15:00:32.914][000000001.224] I/user.crc32 21438764
+[2025-10-16 15:00:32.914][000000001.225] I/user.crc32 21438764
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 197
+[2025-10-16 15:00:32.924][000000001.225] I/user.crc8 243
+[2025-10-16 15:00:32.937][000000001.226] I/user.crc7 50 32
+[2025-10-16 15:00:32.937][000000001.226] I/user.随机数测试
+[2025-10-16 15:00:32.944][000000001.334] I/user.crypto 真随机数 -939521674 5
+[2025-10-16 15:00:33.016][000000001.434] I/user.crypto 真随机数 -1872085296 5
+[2025-10-16 15:00:33.111][000000001.534] I/user.crypto 真随机数 517455164 5
+[2025-10-16 15:00:33.223][000000001.634] I/user.crypto 真随机数 657132096 5
+[2025-10-16 15:00:33.311][000000001.734] I/user.crypto 真随机数 -1080191914 5
+[2025-10-16 15:00:33.421][000000001.834] I/user.crypto 真随机数 -833578535 5
+[2025-10-16 15:00:33.532][000000001.942] I/user.crypto 真随机数 420499958 5
+[2025-10-16 15:00:33.626][000000002.042] I/user.crypto 真随机数 1233025030 5
+[2025-10-16 15:00:33.720][000000002.142] I/user.crypto 真随机数 2138275442 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.crypto 真随机数 182791818 5
+[2025-10-16 15:00:33.830][000000002.242] I/user.totp的密钥
+[2025-10-16 15:00:33.830][000000002.243] I/user.totp 522113 19 29 37
+[2025-10-16 15:00:33.830][000000002.244] I/user.totp 964300 19 30 7
+[2025-10-16 15:00:33.830][000000002.245] I/user.totp 987714 19 30 37
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 037499 19 31 7
+[2025-10-16 15:00:33.830][000000002.246] I/user.totp 699697 19 31 37
+[2025-10-16 15:00:33.830][000000002.247] I/user.totp 548191 19 32 7
+[2025-10-16 15:00:33.845][000000002.248] I/user.totp 747517 19 32 37
+[2025-10-16 15:00:33.845][000000002.249] I/user.totp 243319 19 33 7
+[2025-10-16 15:00:33.861][000000002.249] I/user.totp 147474 19 33 37
+[2025-10-16 15:00:33.877][000000002.250] I/user.totp 039992 19 34 7
+[2025-10-16 15:00:33.877][000000002.251] I/user.totp 628512 19 34 37
+[2025-10-16 15:00:33.877][000000002.252] I/user.totp 529018 19 35 7
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 994006 19 35 37
+[2025-10-16 15:00:33.892][000000002.253] I/user.totp 851359 19 36 7
+[2025-10-16 15:00:33.907][000000002.254] I/user.totp 943237 19 36 37
+[2025-10-16 15:00:33.908][000000002.255] I/user.totp 410702 19 37 7
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 082993 19 37 37
+[2025-10-16 15:00:33.908][000000002.256] I/user.totp 193281 19 38 7
+[2025-10-16 15:00:33.908][000000002.257] I/user.totp 781573 19 38 37
+[2025-10-16 15:00:33.924][000000002.258] I/user.totp 243288 19 39 7
+[2025-10-16 15:00:33.924][000000002.258] I/user.base64 encode MTIz
+[2025-10-16 15:00:33.924][000000002.259] I/user.base64 decode MTIz 123
+[2025-10-16 15:00:33.924][000000002.260] I/user.cipher list ["AES-128-ECB","AES-192-ECB","AES-256-ECB","AES-128-CBC","AES-192-CBC","AES-256-CBC","AES-128-CTR","AES-192-CTR","AES-256-CTR","AES-128-GCM","AES-192-GCM","AES-256-GCM","AES-128-CCM","AES-192-CCM","AES-256-CCM","DES-ECB","DES-EDE-ECB","DES-EDE3-ECB","DES-CBC","DES-EDE-CBC","DES-EDE3-CBC"]
+[2025-10-16 15:00:33.939][000000002.266] I/user.cipher suites 
+[2025-10-16 15:00:33.939][000000002.266] ["TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CCM","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384","TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8","TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CCM","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256","TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA","TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8","TLS-RSA-WITH-AES-256-GCM-SHA384","TLS-RSA-WITH-AES-256-CCM","TLS-RSA-WITH-AES-256-CBC-SHA256","TLS-RSA-WITH-AES-256-CBC-SHA","TLS-RSA-WITH-AES-256-CCM-8","TLS-RSA-WITH-AES-128-GCM-SHA256","TLS-RSA-WITH-AES-128-CCM","TLS-RSA-WITH-AES-128-CBC-SHA256","TLS-RSA-WITH-AES-128-CBC-SHA","TLS-RSA-WITH-AES-128-CCM-8","TLS-RSA-PSK-WITH-AES-256-GCM-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA384","TLS-RSA-PSK-WITH-AES-256-CBC-SHA","TLS-RSA-PSK-WITH-AES-128-GCM-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA256","TLS-RSA-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-256-GCM-SHA384","TLS-PSK-WITH-AES-256-CCM","TLS-PSK-WITH-AES-256-CBC-SHA384","TLS-PSK-WITH-AES-256-CBC-SHA","TLS-PSK-WITH-AES-256-CCM-8","TLS-PSK-WITH-AES-128-GCM-SHA256","TLS-PSK-WITH-AES-128-CCM","TLS-PSK-WITH-AES-128-CBC-SHA256","TLS-PSK-WITH-AES-128-CBC-SHA","TLS-PSK-WITH-AES-128-CCM-8"]
+[2025-10-16 15:00:33.955][000000002.266] I/user.文件hash值测试
+[2025-10-16 15:00:33.955][000000002.269] I/user.md5 D364D04CCD734D2757B25F3216CC431B
+[2025-10-16 15:00:33.955][000000002.273] I/user.sha1 04DA64874D415B1FB9CDD2E89927397D8F48C441
+[2025-10-16 15:00:33.955][000000002.284] I/user.sha256 0C601722B4BD2BC1A76BC3701F4EB646F5119C31702852978C326CD8D7C9212C
+[2025-10-16 15:00:33.955][000000002.287] I/user.hmac_md5 B5F5A687DB904DB67D3311899932DD61
+[2025-10-16 15:00:33.955][000000002.290] I/user.hmac_sha1 2A0B55C290D54ADF2F185EAE460254D267C7CE1F
+[2025-10-16 15:00:33.971][000000002.301] I/user.hmac_sha256 6E443C84D4D7A4721A9A195EB9038EDCFA8A8F60A3F1E8A0090B57B3BAB4942E
+[2025-10-16 15:00:33.971][000000002.301] I/user.md5
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha1
+[2025-10-16 15:00:33.971][000000002.302] I/user.sha256
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_md5
+[2025-10-16 15:00:33.971][000000002.303] I/user.hmac_sha1
+[2025-10-16 15:00:33.971][000000002.304] I/user.hmac_sha256
+[2025-10-16 15:00:33.971][000000002.304] I/user.流式hash测试
+[2025-10-16 15:00:33.986][000000002.304] I/user.md5_stream F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.305] I/user.md5 F5BF3E984432AE6F9F98840951E5CEF3
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5_stream 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.306] I/user.hmac_md5 45527D9407615C3A44F475BB7172752A
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1_stream C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.307] I/user.sha1 C61A2C245CB07A04482CE5B662AE67DBDBE010DB
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1_stream 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:33.986][000000002.308] I/user.hmac_sha1 88471065B8C5F64057418A0A58353A46E7841DE7
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256_stream A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.309] I/user.sha256 A4EBDD541454B84CC670C9F1F5508BAF67FFD3FE59B883267808781F992A0B1D
+[2025-10-16 15:00:34.002][000000002.310] I/user.hmac_sha256_stream EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.hmac_sha256 EAF715932F064E462893B7FE04442E2C25ECF2F7C560820A648D0D94BEAEB581
+[2025-10-16 15:00:34.007][000000002.311] I/user.sha512_stream 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.312] I/user.sha512 3A8529D8F0C7B1AD2FA54C944952829B718D5BEB4FF9BA8F4A849E02FE9A272DAF59AE3BD06DDE6F01DF863D87C8BA4AB016AC576B59A19078C26D8DBE63F79E
+[2025-10-16 15:00:34.007][000000002.313] I/user.hmac_sha512_stream 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.314] I/user.hmac_sha512 18F74340A0048090521796F52A66A45B77AF5981512951B938BFCB026F2D6ED7945B0682731E4E7E3CA72021E5E8AB9810769E48C83F440DC73D6C942215E29E
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum OK 04 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.checksum 357E E4 2
+[2025-10-16 15:00:34.018][000000002.315] I/user.crypto ALL Done
+```