RSA 性能剖析:为什么“Verification”极快而“Signing”极慢?
抱歉,我需要您提供要翻译的具体文本内容(即文章的正文)。目前只看到来源链接,若您把需要翻译的文字粘贴在这里,我就可以按照要求将其译成简体中文并保留原有的格式。
Source: …
谁决定这些数字?
密钥对创建者(密钥对的拥有者)决定这些数字。
下面是一段详细的顺序,回答了三个常见问题:
| 问题 | 回答 | 方式 |
|---|---|---|
| (d) 是如何确定的? | 通过 扩展欧几里得算法 计算得到。 | →→→ |
| 密钥如何分发? | 写入 X.509 证书 并发送。 | →→→ |
| 消息是如何转换为数字的? | 对消息进行填充,然后将其转换为一个巨大的整数。 | →→→ |
角色
| 参与者 | 指数 | 典型大小 | 速度 |
|---|---|---|---|
| 你(客户端) | (e = 65537)(或其他小的公指数) | 小 | 快 |
| 服务器 | (d)(巨大的私指数) | 大 | 慢 |
技术补充
1. 如何计算 (d)(私钥)?
(d) 不是一个随机数。它是满足
[ e \cdot d \equiv 1 \pmod{(p-1)(q-1)} ]
的唯一整数,即 (e) 在模 ((p-1)(q-1)) 下的模乘逆元。
只有知道素数因子 (p) 和 (q) 的服务器,才能使用扩展欧几里得算法求解此方程。
2. 公钥 ((e,n)) 如何分发?
通过数字证书(X.509)。在证书内部可以看到类似以下结构:
Certificate:
Data:
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus: 00:C3:A7:1F:...:4D:
RSA 所使用的二进制指数(平方‑乘)算法如下所示:
// If the current least‑significant bit is 1, multiply
if exponent % 2 == 1 {
result = (result * base) % modulus
}
// Square the base for the next bit
base = (base * base) % modulus
// Shift right to process the next bit
exponent /= 2
return result
RSA 工作流回顾
| 角色 | 使用的指数 | 典型成本 |
|---|---|---|
| 服务器(签名者) | 私钥 (d)(巨大) | 慢(大量模幂运算) |
| 客户端(验证者 / 加密者) | 公钥 (e)(小) | 快(轻量模幂运算) |
繁重的计算留在服务器上(签名),而客户端的验证则成本低廉。这种不对称性导致基于 RSA 的签名在高流量服务器上可能成为瓶颈,从而推动了向 ECDSA 的转变——其验证同样快速,而签名所需的 CPU 资源也大幅降低。
RSA 验证 vs. 签名创建
验证
[ \text{Verification} \equiv s^{e}\pmod n ]
- 公钥指数 (e) 可以任意选择(需满足安全要求)。
- 通常使用数值 65537,因为它能最小化二进制指数运算方法的成本。
65537 的二进制表示
[ 65537_{10}=10000000000000001_{2} ]
- 位长: 17 位
- 汉明重量(1 的个数): 2(最高位和最低位)
二进制指数运算(平方‑乘)
| 步骤 | 操作 | 原因 |
|---|---|---|
| 开始 | (s) | – |
| 0(重复 15 次) | 平方并除以 (n) | 保持中间值较小 |
| 1(最后一次) | 平方、乘以 (s),然后除以 (n) | 完成指数运算 |
只需要 ≈ 17 次模乘,这就是 RSA 验证(以及使用公钥加密)极其快速的原因。
为什么 65537 被称为“奇迹”
| 属性 | 原因 |
|---|---|
| 二进制方法快 | 1 位很少(模式 1…0…1) |
| 素数 | 它是费马素数 (F_{4}=2^{2^{4}}+1) |
| 足够大 | 防止对小模数的攻击 |
签名创建(私钥解密)
[ \text{Signature} \equiv m^{d}\pmod n ]
- 私钥指数 (d) 不能 任意选择。
- 必须满足
[ e,d \equiv 1 \pmod{\phi(n)} ]
其中 (\phi(n)) 为欧拉函数。
- 对于 2048 位模数,(d) 大致与其同等大小(≈ 2048 位),并且看起来是随机的。
示例(说明性)
[ d \approx 1101011\ldots00110_{2} ]
- 位长: ≈ 2048 位(RSA‑2048)
- 汉明重量: ≈ 1024(约占一半位)
签名的二进制指数运算
| 操作 | 大约次数 |
|---|---|
| 平方 | 2048(每位一次) |
| 乘法 | 1024(每个 1 位一次) |
| 模乘总次数 | > 3000 |
因此,签名的速度 比验证慢数百倍。
“如果我们把 (d) 设得很小会怎样?”
选择一个小权重的 (d)(例如,使其像 (e=65537) 那样易于计算)会为诸如 Wiener’s attack 或 Boneh–Durfee attack 之类的攻击打开大门,这些攻击可以仅凭 ((e,n)) 恢复 (d)。
RSA 的安全性依赖于 (d) 是一个大且看似随机的整数;否则私钥可以在不分解 (n) 的情况下被推导出来。
TLS(SSL)中的非对称性能
| 方 | 操作 | 速度 |
|---|---|---|
| 客户端 | 使用公钥加密 ((m^{e})) | 极快 |
| 服务器 | 使用私钥解密 ((c^{d})) | 极慢 |
| 服务器 | 创建签名 ((m^{d})) | 极慢 |
| 客户端 | 验证签名 ((s^{e})) | 极快 |
由于服务器必须执行耗时的私钥运算,许多现代系统倾向于使用 ECDSA(椭圆曲线数字签名算法),它能够显著减轻服务器负担(签名创建速度快,验证速度略慢于 RSA,但仍在可接受范围内)。
摘要:谁持有什么以及他们计算什么
证明者(例如,服务器)——“我是主体”
| 值 | 描述 |
|---|---|
| (m) | 消息的哈希 |
| (d) | 私有指数(大且保密) |
| (n) | 模数(公开) |
| 计算 | (s = m^{d}\pmod n)(签名) |
| 特性 | 二进制方法循环多次 → 计算成本高 |
验证者(例如,客户端)——“签名是否真实?”
| 值 | 描述 |
|---|---|
| (s) | 收到的签名 |
| (m) | 本地计算的消息哈希 |
| (e) | 公用指数(通常为 65537) |
| (n) | 模数(来自证书) |
| 计算 | (\text{Check} = s^{e}\pmod n) |
| 判断 | 如果 (\text{Check}=m),则签名有效 |
| 特性 | e 中的 1 位很少 → 计算瞬间完成 |
RSA 的非对称成本(验证快,签名慢)是影响协议选择的基本设计特性,也推动了椭圆曲线替代方案的采用。