lua-resty-rsa
用于 OpenResty/LuaJIT 的 RSA 加密/解密和签名/验证
$ opm get doujiang24/lua-resty-rsa
名称
lua-resty-rsa - LuaJIT 的 RSA 函数
状态
此库被认为已准备好投入生产使用。
构建状态: [!Travis](https://travis-ci.org/doujiang24/lua-resty-rsa)
描述
此库需要使用 OpenSSL 构建的 nginx,ngx_lua 模块 和 LuaJIT 2.0。
概要
# nginx.conf:
lua_package_path "/path/to/lua-resty-rsa/lib/?.lua;;";
server {
location = /test {
content_by_lua_file conf/test.lua;
}
}
-- conf/test.lua:
local resty_rsa = require "resty.rsa"
local rsa_public_key, rsa_priv_key, err = resty_rsa:generate_rsa_keys(2048)
if not rsa_public_key then
ngx.say('generate rsa keys err: ', err)
end
ngx.say(rsa_public_key)
--[[
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAuw4T755fepEyXTM66pzf6nv8NtnukQTMGnhmBFIFHp/P2vEpxjXU
BBDUpzKkVFR3wuK9O1FNmRDAGNGYC0N/9cZNdhykA1NixJfKQzncN31VJTmNqJNZ
W0x7H9ZGoh2aE0zCCZpRlC1Rf5rL0SVlBoQkn/n9LnYFwyLLIK5/d/y/NZVL6Z6L
cyvga0zRajamLIjY0Dy/8YIwVV6kaSsHeRv2cOB03eam6gbhLGIz/l8wuJhIn1rO
yJLQ36IOJymbbNmcC7+2hEQJP40qLvH7hZ1LaAkgQUHjfi8RvH2T1Jmce7XGPxCo
Ed0yfeFz+pL1KeSWNey6cL3N5hJZE8EntQIDAQAB
-----END RSA PUBLIC KEY-----
]]--
ngx.say(rsa_priv_key)
--[[
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuw4T755fepEyXTM66pzf6nv8NtnukQTMGnhmBFIFHp/P2vEp
xjXUBBDUpzKkVFR3wuK9O1FNmRDAGNGYC0N/9cZNdhykA1NixJfKQzncN31VJTmN
qJNZW0x7H9ZGoh2aE0zCCZpRlC1Rf5rL0SVlBoQkn/n9LnYFwyLLIK5/d/y/NZVL
6Z6Lcyvga0zRajamLIjY0Dy/8YIwVV6kaSsHeRv2cOB03eam6gbhLGIz/l8wuJhI
n1rOyJLQ36IOJymbbNmcC7+2hEQJP40qLvH7hZ1LaAkgQUHjfi8RvH2T1Jmce7XG
PxCoEd0yfeFz+pL1KeSWNey6cL3N5hJZE8EntQIDAQABAoIBAGim1ayIFK8EMQNH
uDyui/Aqcc9WWky0PGTK23irUsXxb1708gQ89WNY70Cj6qBrqZ1VMb3QHPP4FSFN
kh0rJJoi2g+ssm5R5r5KlhTKeFRrQInVC1Y3KhUUUwZa4aWtnhgSJ7Urq1yVhjU4
K7PVkhH1OHBwcp/d1Bd6jd65AgPkY63P+WpcARJkClmQ1RhgoRwThyJdpKrV4/gO
ha0AUGlJNRNvRwiZxP0zaI5C8RdrG96SnVpeYOcD0z/M1HVlkoYMXsXLKttwLfpK
88Igtm6ZJwRpfuMF5VA+9hHaYGCBdGz0B/rMp2fc+EtrOavYQGrWIWi2RL1Qk6Rt
BUyeTgECgYEA9anj4n/cak1MT+hbNFsL31mJXryl1eVNjEZj/iPMztpdS15CmFgj
Kjr9UuintjSiK7Is43nZUWWyP1XQjRhVi2uP7PRIv92QNl/YteWD6tYCInJHKe2J
QqYyZrElezsdayXb5DK6bi1UIYYji90g79N7x6pOR0UnQNQUXTv+Y8ECgYEAwuzl
6Ez4BSXIIL9NK41jfNMa73Utfl5oO1f6mHM2KbILqaFE76PSgEeXDbOKdcjCbbqC
KCGjwyPd+Clehg4vkYXTq1y2SQGHwfz7DilPSOxhPY9ND7lGbeNzDUK4x8xe52hd
MWKdgqeqCK83e5D0ihzRiMah8dbxmlfLAOZ3sPUCgYEA0dT9Czg/YqUHq7FCReQG
rg3iYgMsexjTNh/hxO97PqwRyBCJPWr7DlU4j5qdteobIsubv+kSEI6Ww7Ze3kWM
u/tyAeleQlPTnD4d8rBKD0ogpJ+L3WpBNaaToldpNmr149GAktgpmXYqSEA1GIAW
ZAL11UPIfOO6dYswobpevYECgYEApSosSODnCx2PbMgL8IpWMU+DNEF6sef2s8oB
aam9zCi0HyCqE9AhLlb61D48ZT8eF/IAFVcjttauX3dWQ4rDna/iwgHF5yhnyuS8
KayxJJ4+avYAmwEnfzdJpoPRpGI0TCovRQhFZI8C0Wb+QTJ7Mofmt9lvIUc64sff
GD0wT/0CgYASMf708dmc5Bpzcis++EgMJVb0q+ORmWzSai1NB4bf3LsNS6suWNNU
zj/JGtMaGvQo5vzGU4exNkhpQo8yUU5YbHlA8RCj7SYkmP78kCewEqxlx7dbcuj2
LAPWpiDca8StTfEphoKEVfCPHaUk0MlBHR4lCrnAkEtz23vhZKWhFw==
-----END RSA PRIVATE KEY-----
]]--
local pub, err = resty_rsa:new({ public_key = rsa_public_key })
if not pub then
ngx.say("new rsa err: ", err)
return
end
local encrypted, err = pub:encrypt("hello")
if not encrypted then
ngx.say("failed to encrypt: ", err)
return
end
ngx.say("encrypted length: ", #encrypted)
local priv, err = resty_rsa:new({ private_key = rsa_priv_key })
if not priv then
ngx.say("new rsa err: ", err)
return
end
local decrypted = priv:decrypt(encrypted)
ngx.say(decrypted == "hello")
local algorithm = "SHA1"
local priv, err = resty_rsa:new({ private_key = rsa_priv_key, algorithm = algorithm })
if not priv then
ngx.say("new rsa err: ", err)
return
end
local str = "hello"
local sig, err = priv:sign(str)
if not sig then
ngx.say("failed to sign:", err)
return
end
ngx.say("sig length: ", #sig)
local pub, err = resty_rsa:new({ public_key = rsa_public_key, algorithm = algorithm })
if not pub then
ngx.say("new rsa err: ", err)
return
end
local verify, err = pub:verify(str, sig)
if not verify then
ngx.say("verify err: ", err)
return
end
ngx.say(verify)
方法
要加载此库,
您需要在 ngx_lua 的 lua_package_path 指令中指定此库的路径。例如,
lua_package_path "/path/to/lua-resty-rsa/lib/?.lua;;";
。您使用
require
将库加载到本地 Lua 变量中
local rsa = require "resty.rsa"
generate_rsa_keys
语法:public_key, private_key, err = rsa:generate_rsa_keys(bits)
Generate rsa public key and private key by specifying the number of bits.
new
语法:obj, err = rsa:new(opts)
Creates a new rsa object instance by specifying an options table `opts`.
选项表接受以下选项
public_key
指定公钥 rsa。private_key
指定私钥 rsa。password
指定读取 rsa 密钥的密码。key_type
指定给定密钥的类型。
| key_type
值 | 含义 | | ------------------- | ------ | | rsa.KEY_TYPE.PKCS1 | 输入密钥为 PKCS#1 格式(通常以 -----BEGIN RSA PUBLIC
开头),这是默认值。 | | rsa.KEY_TYPE.PKCS8 | 输入密钥为 PKCS#8 格式(通常以 -----BEGIN PUBLIC
开头)。私钥的 PKCS#8 格式尚未支持。 |
-- creates a rsa object with pkcs#8 format of public key
local resty_rsa = require "resty.rsa"
local pub, err = resty_rsa:new({
public_key = RSA_PKCS8_PUB_KEY,
key_type = resty_rsa.KEY_TYPE.PKCS8,
})
padding
指定您想要加密/解密时的填充模式。algorithm
指定您想要签名/验证时的摘要算法。
| algorithm
值 | 含义 | | ------------------- | ------ | | md4/MD4/RSA-MD4/md4WithRSAEncryption | 使用 md4
摘要 | | md5/MD5/RSA-MD5/md5WithRSAEncryption/ssl2-md5/ssl3-md5 | 使用 md5
摘要 | | ripemd160/RIPEMD160/RSA-RIPEM160/ripemd160WithRSA/rmd160 | 使用 ripemd160
摘要 | | sha/SHA/RSA-SHA/shaWithRSAEncryption | 使用 sha0
摘要 | | sha1/SHA1/RSA-SHA1/sha1WithRSAEncryption/ssl3-sha1 | 使用 sha1
摘要 | | sha224/SHA224/RSA-SHA224/sha224WithRSAEncryption | 使用 sha224
摘要 | | sha256/SHA256/RSA-SHA256/sha256WithRSAEncryption | 使用 sha256
摘要 | | sha384/SHA384/RSA-SHA384/sha384WithRSAEncryption | 使用 sha384
摘要 | | sha512/SHA512/RSA-SHA512/sha512WithRSAEncryption | 使用 sha512
摘要 |
encrypt
语法:encrypted, err = obj:encrypt(str)
decrypt
语法:decrypted, err = obj:decrypt(encrypted)
sign
语法:signature, err = obj:sign(str)
verify
语法:ok, err = obj:verify(str, signature)
性能
首先,始终建议您缓存 rsa 对象。
<http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker>
当我运行此脚本时,我得到了结果
encrypt for 50000 times cost : 2.4110000133514s
decrypt for 50000 times cost : 57.196000099182s
sign for 50000 times cost : 59.169999837875s
verify for 50000 times cost : 1.8230001926422s
local resty_rsa = require "resty.rsa"
local algorithm = "SHA256"
local rsa_public_key, rsa_priv_key, err = resty_rsa:generate_rsa_keys(2048)
if not rsa_public_key then
ngx.say("generate rsa keys err: ", err)
return
end
local pub, err = resty_rsa:new({
public_key = rsa_public_key,
padding = resty_rsa.PADDING.RSA_PKCS1_PADDING,
algorithm = algorithm,
})
if not pub then
ngx.say("new rsa err: ", err)
return
end
local priv, err = resty_rsa:new({
private_key = rsa_priv_key,
padding = resty_rsa.PADDING.RSA_PKCS1_PADDING,
algorithm = algorithm,
})
if not priv then
ngx.say("new rsa err: ", err)
return
end
local num = 5 * 10000
local str = "hello test"
local encrypted, decrypted, err, sig, verify
ngx.update_time()
local now = ngx.now()
local function timer(operation)
ngx.update_time()
local t = ngx.now()
ngx.say(operation, " for ", num, " times cost : ", t - now, "s")
now = t
end
for _ = 1, num do
encrypted, err = pub:encrypt(str)
if not encrypted then
ngx.say("failed to encrypt: ", err)
return
end
end
timer("encrypt")
for _ = 1, num do
decrypted = priv:decrypt(encrypted)
if decrypted ~= str then
ngx.say("decrypted not match")
return
end
end
timer("decrypt")
for _ = 1, num do
sig, err = priv:sign(str)
if not sig then
ngx.say("failed to sign:", err)
return
end
end
timer("sign")
for _ = 1, num do
verify, err = pub:verify(str, sig)
if not verify then
ngx.say("verify err: ", err)
return
end
end
timer("verify")
作者
朱德江 (doujiang24) <doujiang24@gmail.com>
版权和许可
此模块在 MIT 许可下授权。
版权所有 (C) 2014-2014,由朱德江 (doujiang24) <doujiang24@gmail.com>
保留所有权利。
只要满足以下条件,就可以在源代码和二进制形式中以修改或未修改的形式重新分发和使用此软件
源代码的再分发必须保留上述版权声明、此条件列表和以下免责声明。
二进制形式的再分发必须在随发行版提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
本软件由版权持有人和贡献者“按现状”提供,任何明示或暗示的保证,包括但不限于适销性和特定用途适用性的暗示保证,均被排除在外。在任何情况下,版权持有人或贡献者均不对任何直接、间接、附带、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润损失;或业务中断)负责,无论其责任基础如何,无论是合同、严格责任还是侵权行为(包括疏忽或其他原因),均因使用本软件而产生,即使已被告知可能发生此类损害。
另请参阅
ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule
lua-resty-string:https://github.com/openresty/lua-resty-string
作者
doujiang24
许可证
mit
版本
-
用于 OpenResty/LuaJIT 的 RSA 加密/解密和签名/验证 2017-10-22 15:32:42
-
用于 OpenResty/LuaJIT 的 RSA 加密/解密和签名/验证 2016-09-30 07:54:43