增加oauth2.0相关协议接口,并对配置文件进行修改,增加公钥和私钥生成相关函数和使用的测试例子

This commit is contained in:
wanglei 2025-11-11 19:00:22 +08:00
parent e62ba6a9d7
commit abb59406ee
8 changed files with 616 additions and 127 deletions

View File

@ -46,4 +46,12 @@ location /api/system/roles {
location /api/system/users {
access_by_lua_file '${APP_PATH}/src/auth/jwt-auth.lua';
content_by_lua_file '${APP_PATH}/src/api/system/user.lua';
}
######################################################
### oauth2.0 + openIDC 接口文件处理 ###
######################################################
#用户认证登陆相关
location /api/oauth/v2 {
content_by_lua_file '${APP_PATH}/src/api/oauth/oauth.lua';
}

View File

@ -11,7 +11,7 @@ local oauthService = require("service.oauth.oauth")
--定义相关路由前端接口url地址
local routes = {
--------------------------------------------
-------------OAuth2.0认证相关路由配置--------------
------------ OAuth2.0认证相关路由配置 ---------
--------------------------------------------
--获取授权码
{
@ -25,6 +25,12 @@ local routes = {
methods = { "POST" },
handler = oauthService.token,
},
--通过用户名和密码进行验证
{
paths = { "/api/oauth/v2/login" },
methods = { "POST" },
handler = oauthService.userinfo,
},
--根据Access-Token获取相应用户的账户信息
{
paths = { "/api/oauth/v2/userinfo" },

View File

@ -8,6 +8,7 @@ local authDao = require("dao.oauth.oauth")
local validator = require("validator.oauth.oauth")
local cjson = require("cjson.safe")
local token = require("util.uuid")
local jwt = require "resty.jwt"
local _M = {}
@ -18,29 +19,156 @@ function _M:authorize()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorAuthorize(body_data)
local ok = validator.validatorAuthorize(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
resp:send(result)
return
end
--
end
--根据授权码获取Access-Token
function _M:token()
--读取请求体的数据
ngx.req.read_body()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorToken(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
resp:send(result)
return
----获取请求数据
--local body_data = ngx.req.get_body_data()
---- 验证数据是否符合json
--local ok = validator.validatorToken(body_data)
----验证失败则返回
--if not ok then
-- local result = resp:json(0x000001)
-- resp:send(result)
-- return
--end
-- 1. 解析请求参数(支持 form-data 和 json
local content_type = ngx.req.get_headers()["Content-Type"] or ""
local args = {}
if string.find(content_type, "application/json") then
local body = ngx.req.get_body_data()
if not body then
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
args = cjson.decode(body)
else
-- 默认解析 form-urlencoded
args = ngx.req.get_post_args()
end
-- 2. 校验必填参数
local required = {
grant_type = "refresh_token",
refresh_token = true,
client_id = true
}
if args.grant_type ~= required.grant_type then
return ngx.say(cjson.encode({
error = "unsupported_grant_type",
error_description = "grant_type must be 'refresh_token'"
}))
end
if not args.refresh_token or not args.client_id then
return ngx.say(cjson.encode({
error = "invalid_request",
error_description = "missing required parameters"
}))
end
-- 4. 校验 Refresh Token 有效性
local refresh_token = args.refresh_token
local client_id = args.client_id
-- 4.1 检查是否在黑名单(已吊销)
local is_revoked, err = red:get("refresh_blacklist:" .. refresh_token)
if is_revoked == "1" then
return ngx.say(cjson.encode({
error = "token_revoked",
error_description = "refresh_token has been revoked"
}))
end
-- 4.2 校验客户端合法性client_id 与 client_secret 匹配,仅后端客户端需要 secret
local client_secret = args.client_secret or ""
local stored_secret, err = red:get("client:" .. client_id)
if not stored_secret or stored_secret == ngx.null then
return ngx.say(cjson.encode({
error = "invalid_client",
error_description = "client_id not found"
}))
end
-- 机密客户端(如后端服务)必须验证 secret
if stored_secret ~= "public" and stored_secret ~= client_secret then
return ngx.say(cjson.encode({
error = "invalid_client",
error_description = "client_secret invalid"
}))
end
-- 4.3 验证 Refresh Token 签名(假设 Refresh Token 是 JWT 格式)
local refresh_jwt = jwt:verify(jwt_secret, refresh_token)
if not refresh_jwt.valid then
return ngx.say(cjson.encode({
error = "invalid_grant",
error_description = "refresh_token invalid: " .. (refresh_jwt.reason or "unknown")
}))
end
-- 4.4 校验 Token 绑定关系client_id 必须与 JWT 中一致)
if refresh_jwt.payload.client_id ~= client_id then
return ngx.say(cjson.encode({
error = "invalid_grant",
error_description = "refresh_token not bound to client_id"
}))
end
-- 5.1 吊销旧 Refresh Token加入黑名单设置与原有效期一致的过期时间
local ttl = refresh_jwt.payload.exp - ngx.time()
if ttl > 0 then
red:setex("refresh_blacklist:" .. refresh_token, ttl, "1")
end
local access_token_ttl = 10 * 60 --十分钟
local refresh_token_ttl = 7 * 24 * 3600 --7天
-- 5.2 生成新 Access Token
local access_payload = {
sub = refresh_jwt.payload.sub, -- 用户ID
client_id = client_id,
scope = refresh_jwt.payload.scope or "",
exp = ngx.time() + access_token_ttl,
jti = ngx.md5(ngx.time() .. math.random() .. client_id) -- 唯一标识
}
local new_access_token = jwt:sign(jwt_secret, {
header = { typ = "JWT", alg = "HS256" },
payload = access_payload
})
-- 5.3 生成新 Refresh Token滚动刷新
local refresh_payload = {
sub = refresh_jwt.payload.sub,
client_id = client_id,
scope = refresh_jwt.payload.scope or "",
exp = ngx.time() + refresh_token_ttl,
jti = ngx.md5(ngx.time() .. math.random() * 1000 .. client_id)
}
local new_refresh_token = jwt:sign(jwt_secret, {
header = { typ = "JWT", alg = "HS256" },
payload = refresh_payload
})
-- 6. 返回结果
ngx.say(cjson.encode({
access_token = new_access_token,
token_type = "Bearer",
expires_in = access_token_ttl,
refresh_token = new_refresh_token,
refresh_expires_in = refresh_token_ttl,
scope = access_payload.scope,
issued_at = ngx.time(),
jti = access_payload.jti
}))
end
--根据Access-Token获取相应用户的账户信息
@ -50,7 +178,7 @@ function _M:userinfo()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorJson(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
@ -66,7 +194,7 @@ function _M:logout()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorJson(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
@ -82,7 +210,7 @@ function _M:refresh()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorJson(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)
@ -98,7 +226,7 @@ function _M:checklogin()
--获取请求数据
local body_data = ngx.req.get_body_data()
-- 验证数据是否符合json
local ok = validatorJson.validatorJson(body_data)
local ok = validator.validatorJson(body_data)
--验证失败则返回
if not ok then
local result = resp:json(0x000001)

View File

@ -8,6 +8,7 @@ local helpers = require("share.helpers")
local jsonschema = require("jsonschema")
local cjson = require("cjson.safe")
local redis = require("share.redis")
local jwt = require("resty.jwt")
--[[
local workerId = 0 -- 假设当前机器的ID是1范围在[0, 31]之间
@ -19,23 +20,381 @@ local id = snow:generateUniqueId()-- 生成ID
--max =a and b or c--a?b:c
local openssl = require("openssl")
--local openssl = require("openssl")
--
---- 生成RSA密钥对
--local key = openssl.pkey.new {
-- algorithm = "RSA",
-- rsa = {
-- bits = 2048 -- 密钥长度
-- }
--}
--
---- 导出私钥和公钥
--local private_key_pem = key:pem() -- 获取私钥的PEM格式
--local public_key_pem = key:public_key():pem() -- 获取公钥的PEM格式
--
---- 打印密钥
--ngx.say("Private Key:"..private_key_pem)
--ngx.say("\nPublic Key:"..public_key_pem)
--
local openssl = require "resty.openssl"
local digest = require "resty.openssl.digest"
local pkey = require "resty.openssl.pkey"
local str = require "resty.string"
-- 生成RSA密钥对
local key = openssl.pkey.new {
algorithm = "RSA",
rsa = {
bits = 2048 -- 密钥长度
local x509 = require "resty.openssl.x509"
--local pem = require "resty.openssl.pem"
--local rand = require "resty.openssl.rand"
local user_id = "11"
local client_id = "aaaasddd"
local current_time = ngx.time()
local code = ngx.md5(user_id .. client_id .. current_time .. math.random())
ngx.say("code:"..code)
ngx.say("-----")
-- 生成密钥对
local function generate_rsa_keys(length)
-- 生成2048位RSA密钥对
local key, err = pkey.new({
type = "RSA",
bits = length or 2048
})
-- 提取公钥
local pub_pem = key:to_PEM("public")
-- 提取私钥
local priv_pem = key:to_PEM("private")
if not priv_pem or not pub_pem then
return nil, nil, "转换 PEM 格式失败: " .. (err or "未知错误")
end
return pub_pem, priv_pem, nil
end
-- 2. 验签核心函数
-- 参数:
-- pub_key: 公钥对象(由 load_public_key 生成)
-- data: 原始数据(字符串或文件路径)
-- signature: 签名Base64 编码字符串)
-- algorithm: 签名算法(如 "sha256" 对应 RSA-SHA256
local function verify(pub_key, data, signature, algorithm)
-- 处理原始数据(支持字符串或文件)
local data_str
if type(data) == "string" then
-- 判断是否为文件路径
if string.find(data, "^/") or string.find(data, "^%.%/") then
local file, err = io.open(data, "rb")
if not file then
return false, "读取数据文件失败: " .. (err or "未知错误")
end
data_str = file:read("*a")
file:close()
else
data_str = data -- 直接使用字符串数据
end
else
return false, "原始数据格式错误(需字符串或文件路径)"
end
-- 初始化摘要算法(与签名时一致)
local md, err = digest.new(algorithm)
if not md then
return false, "初始化摘要算法失败: " .. (err or "未知错误")
end
-- 计算数据摘要
md:update(data_str)
-- 解码签名Base64 转二进制)
-- 注意JWT 等场景可能用 Base64Url需先转换为标准 Base64
local sig_bin, err = ngx.decode_base64(signature)
if not sig_bin then
return false, "签名 Base64 解码失败: " .. (err or "未知错误")
end
-- 执行验签(默认使用 RSA_PKCS1_PADDING与签名时一致
local ok, err = pub_key:verify(sig_bin, md)
if not ok then
return false, "验签失败: " .. (err or "未知原因")
end
return true
end
-- 3. 示例验证字符串签名RSA-SHA256
local function example()
-- 原始数据(签名前的内容)
local original_data = "hello, world"
-- 1. 生成密钥对
local pub_key, priv_key, err = generate_rsa_keys(2048)
if err then
return --nil, "密钥生成失败: " .. err
end
ngx.say(pub_key)
ngx.say("-----")
ngx.say(priv_key)
ngx.say("-----")
-- 创建签名 Base64 编码,实际应从外部获取,如请求参数)
-- 使用SHA256算法
local digest1 = digest.new("sha256")
-- 更新签名上下文,提供数据以供签名
digest1:update(original_data)
-- 完成签名
local signature, err = digest1:final(priv_key)
if not signature then
ngx.log(ngx.ERR, "Failed to generate signature: ", err)
return
end
ngx.say("签名文件: ", signature)
local decode_date = ngx.encode_base64(signature)
ngx.say("签名加密后(Base64)", decode_date)
local pkeyNew, err = pkey.new(pub_key)
if not pkeyNew then
return
end
-- 验签(算法与签名时一致,这里用 SHA256
local ok, err = verify(pkeyNew, original_data, decode_date, "sha256")
if ok then
ngx.say("验签成功:数据未被篡改,签名有效")
else
ngx.say("验签失败:" .. err)
end
end
-- 执行示例
example()
do
return
end
-- 公钥加密(用于生成测试数据)
local function rsa_encrypt(pub_key, plaintext)
--
local pkey, err = pkey.new(pub_key)
if not pkey or not plaintext then
return nil, "参数错误"
end
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
local ciphertext, err = pkey:encrypt(plaintext, RSA_PKCS1_OAEP_PADDING, oaep_params)
if not ciphertext then
return nil, "加密失败: " .. (err or "未知错误")
end
-- 返回Base64编码的密文便于传输存储
return ngx.encode_base64(ciphertext), nil
end
-- 私钥解密(核心实现)
local function rsa_decrypt(priv_key, encrypted_data)
local pkey, err = pkey.new(priv_key)
if not pkey or not encrypted_data then
return nil, "参数错误(私钥或密文为空)"
end
-- 1. 先解码Base64密文
local ciphertext, err = ngx.decode_base64(encrypted_data)
if not ciphertext then
return nil, "Base64解码失败: " .. (err or "无效密文")
end
-- 2. 设置解密填充方式(必须与加密时一致)
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
-- 3. 执行解密
local result, err = pkey:decrypt(ciphertext, RSA_PKCS1_OAEP_PADDING, oaep_params)
if not result then
return nil, "解密返回空结果"
end
return result, nil -- 返回解密后的原始数据
end
-- 完整测试流程
local function test_rsa_crypto()
-- 1. 生成密钥对
local pub_key, priv_key, err = generate_rsa_keys(2048)
if err then
return nil, "密钥生成失败: " .. err
end
ngx.say(pub_key)
ngx.say("-----")
ngx.say(priv_key)
ngx.say("-----")
-- 2. 原始数据
local original_text = "这是一段需要加密的敏感数据123456"
ngx.say("原始数据: ", original_text)
-- 3. 公钥加密
local encrypted_data, err = rsa_encrypt(pub_key, original_text)
if err then
return nil, "加密失败: " .. err
end
ngx.say("公钥加密后(Base64): ", encrypted_data)
-- 4. 私钥解密
local decrypted_text, err = rsa_decrypt(priv_key, encrypted_data)
if err then
return nil, "私钥解密失败: " .. err
end
ngx.say("私钥解密后: ", decrypted_text)
ngx.say("私钥解密后hex: ", str.to_hex(decrypted_text))
-- 5. 验证结果
if decrypted_text ~= original_text then
return nil, "解密结果不匹配原始数据"
end
-------------------------------
-- 要签名的数据
local md5val = original_text --ngx.md5(original_text) -- 使用MD5作为摘要算法你也可以使用其他如sha256等
--[[
-- 创建签名
-- 使用SHA256算法
local digest1 = digest.new("sha256")
-- 更新签名上下文,提供数据以供签名
digest1:update(md5val)
-- 完成签名
local signature, err = digest1:final(priv_key)
if not signature then
ngx.log(ngx.ERR, "Failed to generate signature: ", err)
return
end
ngx.say("签名文件: ", signature)
local decode_date = ngx.encode_base64(signature)
ngx.say("签名加密后(Base64)", decode_date)
--]]
---- 生成签名------------------
-- 使用SHA256算法
local digestG = digest.new("sha256")
-- 更新签名上下文,提供数据以供签名
digestG:update(md5val)
-- 完成签名
local signature, err = digestG:final(priv_key)
if not signature then
ngx.log(ngx.ERR, "Failed to generate signature: ", err)
return
end
ngx.say("签名数据: ", signature)
local encode_date = ngx.encode_base64(signature)
ngx.say("签名数据加密后(Base64)", encode_date)
---- 验证签名------------------
local pubK, err = pkey.new(pub_key)
if not pubK then
return nil, "参数错误(私钥或密文为空)"
end
local decode_date = ngx.decode_base64(encode_date)
ngx.say("签名数据解密后(Base64)", decode_date)
local is_valid = pubK:verify(encode_date, md5val) -- 使用与签名相同的摘要算法进行验证
if is_valid then
ngx.say("Signature is valid.")
else
ngx.say("Signature is invalid.")
end
-----------------------------------
return true, "加密解密验证成功"
end
-- 1. 生成密钥对
local pub_key, priv_key, err = generate_rsa_keys(2048)
if err then
return nil, "密钥生成失败: " .. err
end
-- 私钥和公钥
local private_key = priv_key
local public_key = pub_key
-- 创建JWT的payload
local payload = {
iss = "https://example.com",
sub = "1234567890",
name = "John Doe",
iat = os.time(),
exp = os.time() + 3600
}
-- 导出私钥和公钥
local private_key_pem = key:pem() -- 获取私钥的PEM格式
local public_key_pem = key:public_key():pem() -- 获取公钥的PEM格式
-- 使用私钥生成JWT
local jwt_obj = jwt:sign(private_key, {
header = {
type = "JWT",
alg = "RS256"
},
payload = payload
})
if not jwt_obj then
ngx.say("Failed to generate JWT")
return
end
-- 打印密钥
ngx.say("Private Key:"..private_key_pem)
ngx.say("\nPublic Key:"..public_key_pem)
ngx.say("Generated JWT: ", jwt_obj)
-- 使用公钥校验JWT
local decoded, res = jwt:verify(public_key, jwt_obj)
if not decoded then
ngx.say("Failed to verify JWT: ", cjson.encode(res))
return
end
ngx.say("JWT is valid: ", cjson.encode(decoded))
--local original_text = "这是一段需要加密的敏感数据123456"
--local key = x509.PKey()
--key:generate_key("rsa", 2048) -- 生成 RSA 密钥2048 位长度
--
--local cert = x509.X509()
--cert:set_version(2) -- 设置证书版本为 2 (RFC 5280)
--cert:set_serial_number({0x01, 0x02, 0x03}) -- 设置序列号
--cert:set_issuer_name([[
-- C=US, ST=Texas, L=Houston, O=Example Inc, OU=IT, CN=example.com
-- ]]) -- 设置颁发者名称
--cert:set_subject_name([[
-- C=US PARTICULARITY, ST=Texas, L=Houston, O=Example Inc, OU=IT, CN=example.com
-- ]]) -- 设置主题名称(与颁发者相同或不同)
--cert:set_pubkey(key) -- 设置公钥
--
--cert:set_not_before(os.time()) -- 设置生效时间(当前时间)
--cert:set_not_after(os.time() + 60*60*24*365) -- 设置过期时间(一年后)
--
--cert:sign(key, "sha256") -- 使用私钥和 SHA256 签名证书
--
--local key_pem = pem.to_pem(key) -- 将密钥转换为 PEM 格式
--local cert_pem = pem.to_pem(cert) -- 将证书转换为 PEM 格式
-- 输出或保存到文件
--ngx.say(key_pem)
--ngx.say(cert_pem)
-- 执行测试
local success, msg = test_rsa_crypto()
if success then
ngx.say("测试成功: \n", msg)
else
ngx.status = 500
ngx.say("测试失败: \n", msg)
end
ngx.say("-----")
--[[
local radix = require("resty.radixtree")
@ -156,7 +515,7 @@ for i = 1, #uid do
table.insert(result, string.sub(charset, rand, rand))
end
print(generate_12char_uuid()) -- 示例输出aB3eF7hJ9kL2
--print(generate_12char_uuid()) -- 示例输出aB3eF7hJ9kL2
--[[
local args = ngx.req.get_uri_args()

View File

@ -4,7 +4,7 @@
--- DateTime: 2025/11/3 11:38
---
local rbac = require("util.rbac")
local rbac = require("util.rsa")
-- 创建RBAC实例
local permission_system = rbac.new()

View File

@ -1,93 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by admin.
--- DateTime: 2025/11/3 11:31
---
local RBAC = {}
RBAC.__index = RBAC
-- RBAC模型初始化
function RBAC.new()
local self = setmetatable({}, RBAC)
self.users = {} -- 用户表: {user_id = {roles = {role1, role2}}}
self.roles = {} -- 角色表: {role_name = {permissions = {perm1, perm2}}}
self.permissions = {} -- 权限表: {perm_name = {resource = "", action = ""}}
return self
end
-- 添加权限
function RBAC:add_permission(perm_name, resource, action)
self.permissions[perm_name] = {
resource = resource,
action = action
}
end
-- 添加角色并分配权限
function RBAC:add_role(role_name, permissions)
self.roles[role_name] = {
permissions = permissions or {}
}
end
-- 分配角色给用户
function RBAC:assign_role(user_id, role_name)
if not self.users[user_id] then
self.users[user_id] = {roles = {}}
end
table.insert(self.users[user_id].roles, role_name)
end
-- 检查用户权限
function RBAC:check_permission(user_id, resource, action)
local user = self.users[user_id]
if not user then return false end
for _, role_name in ipairs(user.roles) do
local role = self.roles[role_name]
if role then
for _, perm_name in ipairs(role.permissions) do
local permission = self.permissions[perm_name]
if permission and permission.resource == resource and permission.action == action then
return true
end
end
end
end
return false
end
-- 获取用户所有权限
function RBAC:get_user_permissions(user_id)
local user_permissions = {}
local user = self.users[user_id]
if not user then return user_permissions end
for _, role_name in ipairs(user.roles) do
local role = self.roles[role_name]
if role then
for _, perm_name in ipairs(role.permissions) do
table.insert(user_permissions, self.permissions[perm_name])
end
end
end
return user_permissions
end
-- 添加角色
--_, err = permit.AddPolicy(roleName, roleId, action)
-- 赋予用户角色
--_, err = permit.AddRoleForUser(user, roleName)
-- 查看具有某角色的所有用户
--res, err = permit.GetUsersForRole(roleName)
-- 移除用户具有的角色
--_, err = permit.DeleteRoleForUser(user, roleName)
-- 移除角色,跟角色相关联的用户都被移除
--_, err = permit.DeleteRole(roleName)
return RBAC

80
src/util/rsa.lua Normal file
View File

@ -0,0 +1,80 @@
local pkey = require "resty.openssl.pkey"
local str = require "resty.string"
local _M = {}
-- 生成密钥对
function _M:generate_rsa_keys(length)
-- 生成2048位RSA密钥对
local key, err = pkey.new({
type = "RSA",
bits = length or 2048
})
-- 提取公钥
local pub_pem = key:to_PEM("public")
-- 提取私钥
local priv_pem = key:to_PEM("private")
if not priv_pem or not pub_pem then
return nil, nil, "转换 PEM 格式失败: " .. (err or "未知错误")
end
return pub_pem, priv_pem, nil
end
-- 公钥加密(用于生成测试数据)
function _M:rsa_encrypt(pub_key, plaintext)
--
local pkey, err = pkey.new(pub_key)
if not pkey or not plaintext then
return nil, "参数错误"
end
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
local ciphertext, err = pkey:encrypt(plaintext, RSA_PKCS1_OAEP_PADDING ,oaep_params)
if not ciphertext then
return nil, "加密失败: " .. (err or "未知错误")
end
-- 返回Base64编码的密文便于传输存储
return ngx.encode_base64(ciphertext), nil
end
-- 私钥解密(核心实现)
function _M:rsa_decrypt(private_key, encrypted_data)
local pkey, err = pkey.new(private_key)
if not pkey or not encrypted_data then
return nil, "参数错误(公钥或密文为空)"
end
-- 1. 先解码Base64密文
local ciphertext, err = ngx.decode_base64(encrypted_data)
if not ciphertext then
return nil, "Base64解码失败: " .. (err or "无效密文")
end
-- 2. 设置解密填充方式(必须与加密时一致)
local oaep_params = {
oaep_md = "sha256", -- 对应pkey.lua中的opts.oaep_md
mgf1_md = "sha256", -- 对应pkey.lua中的opts.mgf1_md
label = nil
}
local RSA_PKCS1_OAEP_PADDING = "4"
-- 3. 执行解密
local result, err = pkey:decrypt(ciphertext, RSA_PKCS1_OAEP_PADDING, oaep_params)
if not result then
return nil, "解密返回空结果"
end
return result, nil -- 返回解密后的原始数据
end
return _M

View File

@ -10,11 +10,12 @@ local _M = {}
-- 定义一个JSON Schema
local schemaAuth = {
{type = "object", properties = {
{name = "username", type = "string"},
{name = "password", type = "string"},
{name = "captcha", type = "string"},
{name = "checkKey", type = "string"},
}, required = {"username", "password"}}
{name = "responseType", type = "string", default = "code"},
{name = "clientId", type = "string", minLength = 10},
{name = "redirectUri", type = "string", minLength = 8},
{name = "state", type = "string"},
{name = "scope", type = "string"},
}, required = {"responseType", "clientId", "redirectUri"}}
}
--获取授权码