You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何decryptRSA函数返回随机结果?RSA加解密程序异常排查

RSA解密失败的问题分析与修复

核心问题1:私钥d的计算完全错误

在rsaKeygen函数中,d = 1%totientN/e这行逻辑完全错误。RSA要求私钥d是e在模totientN下的模逆元,即必须满足(e * d) ≡ 1 mod totientN,而非简单的模运算后做除法。Lua没有内置模逆元函数,需通过扩展欧几里得算法实现。

核心问题2:大数运算精度丢失

Lua默认使用双精度浮点数,处理1.16e+20这类大数时,直接计算msg^e会触发精度溢出,丢失有效数字,导致加密解密结果完全偏离预期。必须改用快速模幂算法,在计算过程中持续取模,避免大数溢出。

核心问题3:密钥生成逻辑瑕疵(非致命但不合理)

p和q的随机范围逻辑混乱:初始给p选50000-100000的数,非素数就换成1-1000;q则相反。这会导致其中一个素数大概率过小,降低密钥安全性,建议统一素数随机范围。


修复后的代码

1. 实现扩展欧几里得算法求模逆元

function modinv(a, m)
    local m0 = m
    local y = 0
    local x = 1
    if m == 1 then
        return 0
    end
    while a > 1 do
        local q = math.floor(a / m)
        local t = m
        m = a % m
        a = t
        t = y
        y = x - q * y
        x = t
    end
    if x < 0 then
        x = x + m0
    end
    return x
end

2. 修复密钥生成函数

function rsaKeygen()
    -- 统一素数随机范围,确保p、q均为大素数
    local p = math.random(50000, 100000)
    while not isprime(p) do
        p = math.random(50000, 100000)
    end
    local q = math.random(50000, 100000)
    while not isprime(q) do
        q = math.random(50000, 100000)
    end
    -- 确保p≠q,避免n为平方数
    while p == q do
        q = math.random(50000, 100000)
        while not isprime(q) do
            q = math.random(50000, 100000)
        end
    end
    local n = p * q
    local totientN = carmichael(n)
    local e = 2^16 + 1 -- 65537,常用安全公钥指数
    -- 确保e与totientN互质
    while gcd(e, totientN) ~= 1 do
        e = e + 2
    end
    local d = modinv(e, totientN)
    return e, d, n
end

3. 实现快速模幂算法修复加密解密

function modpow(base, exp, mod)
    local result = 1
    base = base % mod
    while exp > 0 do
        if exp % 2 == 1 then
            result = (result * base) % mod
        end
        exp = math.floor(exp / 2)
        base = (base * base) % mod
    end
    return result
end

function encryptRSA(e, n, msg)
    local msgNum = plainToNum(msg)
    -- RSA要求明文数值必须小于n,否则需分段加密
    if msgNum >= n then
        error("明文过大,需分段处理")
    end
    return modpow(msgNum, e, n)
end

function decryptRSA(d, n, msg)
    return modpow(msg, d, n)
end

关键说明

  • 模逆元是RSA私钥计算的核心,必须通过扩展欧几里得算法实现,不能直接用除法。
  • 快速模幂算法通过每一步取模,避免了大数运算的精度损失,保证数值始终在合理范围内。
  • 必须确保明文数值小于n,否则需要对明文进行分段处理,这是RSA的基本要求。

内容的提问来源于stack exchange,提问作者Overo3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:33:13