RSA 密码模拟器 返回
密码学·教育演示

RSA 密码模拟器 — 密钥生成与加密解密

从两个素数 p、q 生成密钥对 (n, e, d),实现平文 m 的加密和解密的 RSA 概念演示。使用教育用小规模数值,以手工可追踪的水平体验公钥密码的工作原理。

参数设置
素数 p
素数 q
公开指数 e
平文 m

如果 p、q 不是素数,将被舍入到最近的素数。e 需要满足 gcd(e, φ(n)) = 1。

计算结果
公开模数 n=p·q
欧拉函数 φ(n)
秘密指数 d
密文 c=m^e mod n
密钥对与加密流

左=密钥对 (n, φ, e, d)/右=加密流 m → [^e mod n] → c → [^d mod n] → m'

理论·主要公式

RSA 是以素因数分解的困难性为安全基础的公钥密码。密钥生成按以下步骤进行。

选择两个素数 p、q,计算公开模数和欧拉函数:

$$n = p\,q, \qquad \varphi(n) = (p-1)(q-1)$$

公开指数 e 与 φ(n) 互质:gcd(e, φ(n)) = 1。秘密指数 d 是 e 在模 φ(n) 意义下的逆元(用扩展欧几里得算法计算):

$$e\,d \equiv 1 \pmod{\varphi(n)}$$

加密和解密都用模 n 下的幂运算进行:

$$c = m^{e} \bmod n, \qquad m' = c^{d} \bmod n$$

前提条件为 0 ≤ m < n。根据费马-欧拉定理,m' = m 被保证成立。

RSA 密码模拟器是什么

🙋
我听说过 RSA 这个名字,但最终它是在做什么?我打开了这个模拟器,出现了很多数字,有点吓到我了。
🎓
简单来说,就是秘密地拥有两个素数 p、q,只公开它们的乘积 n = p·q。在模拟器的初始值中,p=11,q=13,所以 n=143。虽然任何人都能看到 n,但从 n 进行"素因数分解"来找出原始的 p、q 非常困难,这就是安全性的原理。看看"密钥对"的框,应该能看到 n 和 e 是公开的,而 p、q、d 是秘密的,都用不同颜色区分了。
🙋
那"e"和"d"是什么?当我把平文 m 设为 42 时,密文变成了 81。
🎓
e 是公开指数,d 是秘密指数。加密是用 $c = m^e \bmod n$ 来做的,用初始值的话就是 $42^7 \bmod 143 = 81$。这个数字就显示在"c"框里。手工计算的话,$42^2 = 1764 \equiv 48 \pmod{143}$,$42^4 \equiv 48^2 = 2304 \equiv 16$,最后 $42^7 = 42 \cdot 48 \cdot 16 = 32256 \equiv 81 \pmod{143}$。这个范围内用电算器是能追踪的。
🙋
那解密的部分呢?显示"d=103",但我根本没法手工计算 $81^{103}$ 啊…
🎓
那个地方用到了"模幂运算(modular exponentiation)"这种技巧。不是一下子生成巨大的数字,而是用二进制展开,每次都取模 n,通过多次平方来计算的。模拟器内部用 BigInt 和二进制展开来计算。重要的是结果,$81^{103} \bmod 143$ 确实回到了 42。如果"m'"框显示为绿色,值是 42,那就是解密成功了。
🙋
为什么会回到原来的值?太神奇了…
🎓
费马-欧拉定理在这里起作用了。因为 d 的选择满足 $e \cdot d \equiv 1 \pmod{\varphi(n)}$,所以 $(m^e)^d = m^{ed} \equiv m \pmod n$ 就成立了。在实际应用中,p、q 会是 1024 位级别的,n 会是 2048 位以上,但原理和这个演示是一样的。试试改变"e"的值,看看 d 怎么变,c 也会变成完全不同的值。

常见问题

一旦 p、q 泄露,φ(n) = (p−1)(q−1) 就能立即计算出来,从 e 可以用扩展欧几里得算法求出 d,任何人都能重新构造秘密密钥并解密消息。RSA 的安全性核心在于"分解 n 找出 p、q 在现实时间内是不可能的"这个假设,一旦 p、q 直接被知道,这个假设就毫无意义了。
65537 = 2¹⁶ + 1 是素数(费马素数),与几乎所有的 φ(n) 都互质。而且它的二进制表示"100000000000000001"中只有两个 1,所以用二进展开法计算模幂时,乘法次数极少,加密速度很快。同时,它足够大,避免了 e=3 这样太小的指数容易遭到的 Coppersmith 类型攻击,这种平衡使得它成为事实上的标准。
绝对不行。这个工具是为了直观理解仕组而设计的教育演示,p、q 被限制在 100 以下的小素数。n 最多只有 3 到 4 位数,任何人用几秒钟就能进行素因数分解。实际应用中,n 需要是 2048 位以上(十进制 600 位以上)。而且实现中必须使用填充(OAEP 等)和随机化,直接使用教科书 RSA 是禁忌。
RSA 是在模 n 下进行计算的,所以平文 m 必须满足 0 ≤ m < n。比如 p=3, q=5,那么 n=15,而 m=42 显然超出范围。这种情况下,即使加密了,解密也只能恢复"m mod n",无法回到原始的 42。需要增大 p、q 使得 n 超过 100,或者让 m 更小。实际实现中,长消息通常会被分割成"小于 n 的块"进行加密,或与对称密钥密码组合使用。

实际应用

HTTPS / TLS 的密钥交换和签名:当浏览器连接网站时显示的"锁形图标"背后,RSA 被广泛用于服务器证书签名验证和通信初期的共同密钥交换。沿着证书链向上查找,会发现根 CA 的公钥进行的 RSA 签名。

PGP / GnuPG 的电子邮件加密和签名:个人和企业使用 RSA 密钥对来进行电子邮件的加密和签名,以及软件发布的签名(如 Linux 发行版的包签名等)。这类长期维护身份的用途与 RSA 的特性很吻合,人们用指纹(fingerprint)来验证密钥身份的文化已经根深蒂固。

SSH 公钥认证:广泛用于服务器远程登录的 ssh-rsa 密钥,正是本演示升级版本的实现。客户端用秘密密钥 d 对挑战进行签名,服务器用已注册的公钥 (n, e) 进行验证。虽然最近向 Ed25519 的迁移在进行,但 RSA 4096 位密钥仍然很常用。

个人编号卡和 IC 卡认证:在 e-Tax 登录和身份验证中使用的 IC 卡内部,RSA 秘密密钥被安全地存储在专用区域,签名计算在卡内完成。由于秘密密钥从不离开卡片,即使个人电脑被入侵,密钥也能受到保护。

常见误解和注意事项

最常见的误解就是直接实现"教科书 RSA"就能安全这种想法。本模拟器展示的是"确定性的" RSA,同一个平文每次加密都会产生相同的密文。这样的话,可以用字典攻击瞬间识别"典型的短消息"。实现中必须配合 OAEP(最优非对称加密填充)等包含随机数的填充方案,使得同一平文每次加密产生不同的密文。对于签名用途,则推荐使用 PSS 填充。

次常见的误解是只用"位数"来评估密钥长度。"RSA 2048 位"听起来像是与 2048 位对称密钥相同的安全性,但实际需要用"等价安全性"来衡量。RSA 2048 位的安全性约相当于对称密钥的 112 位。要与 AES-128 等价,需要 RSA 3072 位;要与 AES-256 等价,需要 RSA 15360 位。这是 NIST 指南的建议。密钥长度不能跨算法方案进行简单比较。

最后要注意的是,"用公钥加密,用私钥解密"这个对应关系并非始终成立。在数学上 RSA 是对称的,既可以(e 加密 → d 解密),也可以(d 加密 → e 解密)。前者称为"加密",后者称为"签名"。不过在实际应用中直接混用是危险的,需要针对不同用途使用不同的密钥、遵循 PKCS#1 等规范。本演示为了直观展示数学原理而尽量简化了,但实现中一定要避免"用加密密钥来签名"这样的误用。

使用指南

  1. 用滑块选择素数 p(47~97)和 q(53~127),生成公开模数 n=p·q
  2. 自动计算欧拉函数 φ(n)=(p-1)(q-1),验证公开指数 e 与之的最大公约数为 1
  3. 用扩展欧几里得算法求秘密指数 d,验证 e·d≡1(mod φ(n)) 的关系
  4. 输入平文 m(小于 n 的整数),计算密文 c=m^e mod n 并输出
  5. 通过解密处理 m'=c^d mod n 恢复原平文,确认加密和解密的对称性

具体计算例子

选择 p=61、q=53 时,n=3,233,φ(n)=3,120。选择 e=17 时,扩展欧几里得算法计算出 d=2,753。平文 m=65 加密时,c=65^17 mod 3,233=2,790,解密时 c^2753 mod 3,233=65 被恢复。通过这一计算过程,可以实际验证作为 RSA 数学基础的费马小定理和欧拉定理。

实务上的注意事项