JavaScript实现RSA算法解密结果异常,e或d生成逻辑排查求助
问题排查结果
- 首先你的公钥e、私钥d的生成逻辑完全符合RSA数学规则,不存在逻辑错误:你当前参数下生成的e=5、d=29,确实满足
5*29 mod 72 = 1,和ϕ(n)互质的要求也达标。 - 核心错误是大指数幂运算触发了JS的精度丢失:JS内置的Number类型是双精度浮点数,只能精确表示小于2^53的整数,你计算
e_m ** d时,23的29次方远大于2^53,计算过程中整数精度丢失,最终取模结果自然错误。 - 次要问题是变量声明语法不规范:你初始化变量时
p=13、q=7后都漏了逗号,导致后续的n、T、d都脱离了var声明范围,变成隐式全局变量,严格模式下会直接抛出语法错误。
修复方案
你需要替换直接用**算幂再取模的逻辑,改用快速模幂算法计算,可以借助JS的BigInt类型避免中间计算精度溢出,修复后的完整代码如下:
// 快速模幂:计算 (base^exponent) % mod function modPow(base, exponent, mod) { let result = 1n; base = BigInt(base) % BigInt(mod); exponent = BigInt(exponent); mod = BigInt(mod); while (exponent > 0n) { if (exponent % 2n === 1n) { result = (result * base) % mod; } exponent = exponent >> 1n; base = (base * base) % mod; } return Number(result); } function gcd(k, n) { return k ? gcd(n % k, k) : n; } // 修复变量声明的逗号缺失问题 var m = 4, // 明文 p = 13, q = 7, n = p * q, T = (q - 1) * (p - 1), d = 1, // 初始化d为1,避免从0开始循环的冗余计算 e; // 计算公钥e for (let i = 2; i < T; i++) { if(gcd(i,T) == 1) { e = i; break; } } // 计算私钥d while (e * d % T != 1) d++; // 改用快速模幂计算加解密 var e_m = modPow(m, e, n), // 加密 d_m = modPow(e_m, d, n); // 解密 console.log(`m: ${m}\np: ${p}\nq: ${q}\nn: ${n}\nT: ${T}\n\ne: ${e}\nd: ${d}\n\nencrypted: ${e_m}\ndecrypted: ${d_m}`);
运行后输出的decrypted结果为4,符合预期。
内容的提问来源于stack exchange,提问作者mmm107
相关产品推荐
相关产品推荐

