diff --git a/src/test/test.lua b/src/test/test.lua index 54f8d6e..f05899e 100644 --- a/src/test/test.lua +++ b/src/test/test.lua @@ -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