rsa - RSA加密解密
作者:王城钧
一、概述
rsa 库提供基于 RSA 非对称加密的安全通信能力,支持 PEM 格式密钥的加密/解密、数字签名/验签功能,适用于设备与服务器间的数据保密传输和身份认证。
二、核心示例
1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/rsa
-- 注意:本demo需要用到公钥和私钥, demo目录中的公钥私钥文件是演示用的, 实际使用请自行生成
PROJECT = "rsademo"
VERSION = "1.0.1"
log.info("main", PROJECT, VERSION)
local function rsa()
-- 为了日志能正常显示出来, 这里特意延时2秒, 实际使用中不需要
sys.wait(2000)
-- 检查是否带rsa库, 没有就提醒一下吧
if not rsa then
log.warn("main", "this demo need rsa lib!!!")
return
end
-- 读取公钥并马上加密数据
local res = rsa.encrypt((io.readFile("/luadb/public.pem")), "abc")
-- 打印结果
log.info("rsa", "encrypt", res and #res or 0, res and res:toHex() or "")
-- 下面是解密, 通常不会在设备端进行, 这里主要是演示用法, 会很慢
if res then
-- 读取私钥, 然后解码数据
local dst = rsa.decrypt((io.readFile("/luadb/privkey.pem")), res, "")
log.info("rsa", "decrypt", dst and #dst or 0, dst and dst:toHex() or "")
end
-- 演示签名和验签
local hash = crypto.sha1("1234567890"):fromHex()
-- 签名通常很慢, 通常是服务器做
local sig = rsa.sign((io.readFile("/luadb/privkey.pem")), rsa.MD_SHA1, hash, "")
log.info("rsa", "sign", sig and #sig or 0, sig and sig:toHex() or "")
if sig then
-- 验签是很快的
local ret = rsa.verify((io.readFile("/luadb/public.pem")), rsa.MD_SHA1, hash, sig)
log.info("rsa", "verify", ret)
end
end
sys.taskInit(rsa)
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
三、常量详解
核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
rsa 核心库没有常量。
四、函数详解
rsa.encrypt(key, data)
功能
RSA 加密过程通过解析 PEM 格式公钥,对不超过公钥位数一半的待加密数据执行 RSA-PKCS1_V1.5 加密运算,成功返回二进制密文数据,失败时返回 nil。
参数
key
参数含义:表示公钥数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:仅支持PEM格式;
参数示例:(io.readFile("/luadb/public.pem"));
data
参数含义:表示待加密数据;
数据类型:string;
取值范围:不能超过公钥位数的一半;
例如 2048bit(256字节,1字节等于8位)的公钥, 只能加密128字节的数据;
是否必选:必须传入此参数;
注意事项:仅支持PEM格式;
参数示例:"abc";
返回值
local res = rsa.encrypt(key,data)
res
含义说明:加密成功后的数据,若失败会返回nil;
数据类型:string或者nil;
取值范围:暂无;
注意事项:暂无;
返回示例:使用log.info("rsa", "encrypt", res and #res or 0, res and res:toHex() or "")
打印的结果如下:
rsa encrypt 256
1586CB23B2004F6208A1816DA209896F0CD026A53DD53771067BC64E13
16C8E97A51F4595E83B7EF68B36E689C25F4D49ABB7F9E3DA7A8FAB3AB
F45986F295ABF6D5FA5E140B46EFA258578DA6E9DA6A91B7253AF5DFFC
86C93C0DE90B444ACDB564C5ED3EFBA09CC1A09B369C15362BFFA40E61
1FE80D2A78C37B42BC09EFBDCE18BD3475BCD42E782031BADA8330BF32
EEAAFF76294B8B34F075D8C39EC970E44DD1FABDD1432C1D5F317E815C
7ADCFF9E0B85D659794BCCC3989188036C2CF2ED05369A4B1EF9EAE83F
8C7215D0CA6D23029CCC940E4FDA1CCEF3AEB2D16A1D19F5FEE50F6858
A83AC2FA79B4C945F55DAF9C6D8CDF1E98DCA34F7E55F07E;
示例
-- 下面代码中的 "abc" 是待加密数据
local res = rsa.encrypt((io.readFile("/luadb/public.pem")), "abc")
-- 打印结果
log.info("rsa", "encrypt", res and #res or 0, res and res:toHex() or "")
rsa.decrypt(key, data, pwd)
功能
RSA 解密过程通过私钥解析(支持可选密码)、数据长度校验,对加密数据执行解密运算,成功返回原始二进制数据,失败或出错时返回 nil。 参数
key
参数含义:表示私钥数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:仅支持PEM格式;
参数示例:(io.readFile("/luadb/privkey.pem"));
data
参数含义:表示待解密数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:"1586CB23B2004F6208A1816DA209896F0CD026A53DD53771067BC64E
1316C8E97A51F4595E83B7EF68B36E689C25F4D49ABB7F9E3DA7A8FA
B3ABF45986F295ABF6D5FA5E140B46EFA258578DA6E9DA6A91B7253A
F5DFFC86C93C0DE90B444ACDB564C5ED3EFBA09CC1A09B369C15362B
FFA40E611FE80D2A78C37B42BC09EFBDCE18BD3475BCD42E782031BA
DA8330BF32EEAAFF76294B8B34F075D8C39EC970E44DD1FABDD1432C
1D5F317E815C7ADCFF9E0B85D659794BCCC3989188036C2CF2ED0536
9A4B1EF9EAE83F8C7215D0CA6D23029CCC940E4FDA1CCEF3AEB2D16A
1D19F5FEE50F6858A83AC2FA79B4C945F55DAF9C6D8CDF1E98DCA34F
7E55F07E";
pwd
参数含义:表示私钥的密码;
数据类型:string;
取值范围:暂无;
是否必选:可选传入此参数;
注意事项:暂无;
参数示例:暂无;
返回值
local dst = rsa.decrypt(key,data,pwd)
dst
含义说明:解密成功后的数据,若失败会返回nil;
数据类型:string或者nil;
取值范围:暂无;
注意事项:暂无;
返回示例:使用log.info("rsa", "decrypt", dst and #dst or 0, dst and dst:toHex() or "")
打印的结果如下:
rsa decrypt 3 616263;
示例
-- 注意, 解密通常很慢, 建议在服务器端进行
-- res 是待解密的数据
local dst = rsa.decrypt((io.readFile("/luadb/privkey.pem")), res, "")
log.info("rsa", "decrypt", dst and #dst or 0, dst and dst:toHex() or "")
rsa.sign(key, md, hash, pwd)
功能
RSA 签名过程通过私钥解析、指定哈希算法及可选密码,对输入哈希值进行签名运算,成功生成并返回二进制签名数据,失败或出错时返回 nil。
参数
key
参数含义:表示私钥数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:仅支持PEM格式;
参数示例:(io.readFile("/luadb/privkey.pem"));
md
参数含义:签名模式;
数据类型:number;
取值范围:rsa.MD_SHA1,rsa.MD_SHA256,rsa.MD_MD5,rsa.MD_SHA224;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:rsa.MD_SHA1,rsa.MD_SHA256;
hash
参数含义:hash数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:如果是HEX字符串,记得fromHex转二进制数据;
参数示例:hash;
pwd
参数含义:私钥密码;
数据类型:string;
取值范围:暂无;
是否必选:可选传入此参数;
注意事项:如果是HEX字符串,记得fromHex转二进制数据;
参数示例:"123456";
返回值
local sig= rsa.sign(key, md, hash, pwd)
sig
含义说明:成功返回sig数据, 否则返回nil;
数据类型:string或者nil;
取值范围:暂无;
注意事项:暂无;
返回示例:使用log.info("rsa", "sign", sig and #sig or 0, sig and sig:toHex() or "")
打印结果如下:
rsa sign 256
2A526049BSDOFFDF370EE1EB37E87A1C054B387386C635B4DD46E3970F90D08732D4CC
1B38EA9153B6C52AE2602C55272828D4F627E1BF8B94BC02C79DB1F0462F3A5A654D9D
AF2794F4DBECIA691FE6DOC45SCA0DCE9B9ACDFCAC79D9CFF46740248131E58ACE00BE
7DA8S37F1E6SS0F17C204ADDD79C7356C57D9FD4ACC7006BA2E248B9FEFE002EBFCCF8
5B5A8DA0D1369D6463D24F8CA24C2E314CCE39DF43A0SEB3840BDC1298F0361D13HE2E
F3C87A76D82696873B8FEDD748DF54D70CB3D2A5072D137954BFA4FA990D2C01D8061F
0F2E27DF813DAB751A06F38C8327E574EDCC52F21A98EC2E6CD9A8A8AFC9DA0475EB75
47D0
示例
local sig = rsa.sign((io.readFile("/luadb/privkey.pem")), rsa.MD_SHA1, hash, "")
log.info("rsa", "sign", sig and #sig or 0, sig and sig:toHex() or "")
rsa.verify(key, md, hash, sig)
功能
RSA 验签过程首先通过公钥解析、指定哈希算法及签名模式,验证待验签数据与签名是否匹配,成功返回 true,失败返回 false,出错返回 nil。
参数
key
参数含义:表示公钥数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:仅支持PEM格式;
参数示例:(io.readFile("/luadb/public.pem"));
md
参数含义:签名模式;
数据类型:number;
取值范围:rsa.MD_SHA1,rsa.MD_SHA256,rsa.MD_MD5,rsa.MD_SHA224;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:rsa.MD_SHA1,rsa.MD_SHA256;
hash
参数含义:hash数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:如果是HEX字符串,记得fromHex转二进制数据;
参数示例:暂无;
sig
参数含义:私钥签名后的数据;
数据类型:string;
取值范围:暂无;
是否必选:必须传入此参数;
注意事项:如果是HEX字符串,记得fromHex转二进制数据;
参数示例:"2A526049B5D0FFFDF370EE1EB37E87A1C054B387386C635B4DD46E39
70F90D08732D4CC1B338EA9153B6C52AE22602C55272C828D4F627E1
BF8B994BC02C79DB1F0462F3A5A654D9DAF2794F4D8EC1A691FE6D0C
455CA0DCE9B9ACDFC44C79D9CFFF46740248131EE58ACE00BE7DA853
7F1E6550F17C204ADDD79C735C57D9FD4ACC7006BA22E248B9FEFE00
2E8FCCCF85B5A8DA0D133669D6463D24F8CA24C2E314CCCE39DF43A0
5EB33840BDC1298F0361D13FE2EEF3C87A76D826968873B8FEDD748D
F54D70CB3D2A5072D137954BFA4FA990D2C01D8061FF0F2E27DF813D
A8751A06F38C83827E574EDCC52F271A98EC2E6CD9A8A8AFC9DA0475
EB7547D0";
返回值
local ret = rsa.verify(key, md, hash, sig)
ret
含义说明:验签是否成功,成功返回true,失败返回false;
数据类型:boolean或者nil;
取值范围:true或者false或者nil;
注意事项:暂无;
返回示例:true;
示例
local ret = rsa.verify((io.readFile("/luadb/public.pem")), rsa.MD_SHA1, hash, sig)
log.info("rsa", "verify", ret)
五、产品支持说明
目前合宙主流模组都支持 rsa 核心库。