修改openssl进行验签功能错误的问题

This commit is contained in:
wanglei 2025-11-11 19:26:53 +08:00
parent abb59406ee
commit e422654320

View File

@ -55,37 +55,86 @@ ngx.say("code:"..code)
ngx.say("-----")
-- 生成密钥对
-- 生成RSA密钥对
local function generate_rsa_keys(length)
-- 生成2048位RSA密钥对
local key, err = pkey.new({
type = "RSA",
bits = length or 2048
})
if not key then
return nil, nil, "生成密钥对失败: " .. (err or "未知错误")
end
-- 提取公钥
local pub_pem = key:to_PEM("public")
-- 提取私钥
local priv_pem = key:to_PEM("private")
-- 提取公钥PEM格式
local pub_pem, err = key:to_PEM("public")
if not pub_pem then
return nil, nil, "提取公钥失败: " .. (err or "未知错误")
end
if not priv_pem or not pub_pem then
return nil, nil, "转换 PEM 格式失败: " .. (err or "未知错误")
-- 提取私钥PEM格式
local priv_pem, err = key:to_PEM("private")
if not priv_pem then
return nil, nil, "提取私钥失败: " .. (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 function sign(priv_key_pem, data, algorithm)
-- 加载私钥
local priv_key, err = pkey.new(priv_key_pem)
if not priv_key then
return nil, "加载私钥失败: " .. (err or "未知错误")
end
-- 处理原始数据(字符串或文件路径)
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 nil, "读取数据文件失败: " .. (err or "未知错误")
end
data_str = file:read("*a")
file:close()
else
-- 直接使用字符串
data_str = data
end
else
return nil, "原始数据格式错误(需字符串或文件路径)"
end
-- 计算数据摘要
local md, err = digest.new(algorithm)
if not md then
return nil, "初始化摘要算法失败: " .. (err or "未知错误")
end
md:update(data_str)
-- 使用私钥对摘要签名RSA-PKCS#1填充
local signature, err = priv_key:sign(md)
if not signature then
return nil, "签名生成失败: " .. (err or "未知错误")
end
-- 签名转为Base64编码便于传输
return ngx.encode_base64(signature), nil
end
-- 验签函数(使用公钥)
local function verify(pub_key_pem, data, signature_b64, algorithm)
-- 加载公钥
local pub_key, err = pkey.new(pub_key_pem)
if not pub_key then
return false, "加载公钥失败: " .. (err or "未知错误")
end
-- 处理原始数据
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
@ -94,78 +143,63 @@ local function verify(pub_key, data, signature, algorithm)
data_str = file:read("*a")
file:close()
else
data_str = data -- 直接使用字符串数据
data_str = data
end
else
return false, "原始数据格式错误(需字符串或文件路径)"
end
-- 初始化摘要算法(与签名时一致)
-- 解码Base64签名为二进制
local signature, err = ngx.decode_base64(signature_b64)
if not signature then
return false, "签名Base64解码失败: " .. (err or "未知错误")
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)
-- 公钥验签
local ok, err = pub_key:verify(signature, md)
if not ok then
return false, "验签失败: " .. (err or "未知原因")
end
return true
return true, nil
end
-- 3. 示例:验证字符串RSA-SHA256
-- 示例:完整流程(生成密钥对 → 签名 → 验签)
local function example()
-- 原始数据(签名前的内容)
local original_data = "hello, world"
local original_data = "hello, world" -- 原始数据
local algorithm = "sha256" -- 签名算法
-- 1. 生成密钥对
-- 1. 生成RSA密钥对
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)
ngx.say("密钥对生成失败: ", err)
return
end
ngx.say("签名文件: ", signature)
local decode_date = ngx.encode_base64(signature)
ngx.say("签名加密后(Base64)", decode_date)
ngx.say("公钥:\n", pub_key)
ngx.say("\n私钥:\n", priv_key)
ngx.say("\n------------------------")
local pkeyNew, err = pkey.new(pub_key)
if not pkeyNew then
-- 2. 使用私钥生成签名
local signature_b64, err = sign(priv_key, original_data, algorithm)
if err then
ngx.say("签名失败: ", err)
return
end
ngx.say("生成的签名(Base64):\n", signature_b64)
ngx.say("\n------------------------")
-- 验签(算法与签名时一致,这里用 SHA256
local ok, err = verify(pkeyNew, original_data, decode_date, "sha256")
-- 3. 使用公钥验签
local ok, err = verify(pub_key, original_data, signature_b64, algorithm)
if ok then
ngx.say("验签成功:数据未被篡改,签名有效")
ngx.say("验签成功:数据完整且签名有效")
else
ngx.say("验签失败:" .. err)
ngx.say("验签失败:", err)
end
end