Archipelago

Lec 6数字签名:RSA

讲义完成更新于 2026-09-16

Lec 6 数字签名:RSA

MIT 6.1600 · Introduction to Computer Security

TL;DR

  • RSA 的陷门置换来自模数分解困难,但“教科书式”直接对消息做幂运算具有乘法可塑性,不能作为安全签名。
  • RSA-FDH 和 RSA-PSS 通过哈希与随机化把消息编码到合适域;实践中应使用经过标准化的 PSS,而非自行设计填充。
  • ECDSA 与 Schnorr 以离散对数为基础并显著缩短密钥;每次签名的 nonce 必须唯一且不可预测,否则私钥可被恢复。

1. RSA 数学基础

1.1 欧拉函数

给定 n=p⋅qn = p \cdot q(p,qp, q 为大素数):

ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1)

欧拉定理:若 gcd⁡(a,n)=1\gcd(a, n) = 1,则:

aϕ(n)≡1(modn)a^{\phi(n)} \equiv 1 \pmod{n}

1.2 RSA 密钥生成

p,q←$大素数,n=pqp, q \xleftarrow{\$} \text{大素数}, \quad n = pq e:gcd⁡(e,ϕ(n))=1(通常 e=65537)e: \gcd(e, \phi(n)) = 1 \quad (\text{通常 } e = 65537) d≡e−1(modϕ(n))d \equiv e^{-1} \pmod{\phi(n)}

公钥:(n,e)(n, e);私钥:(n,d)(n, d)(或等价地 (p,q,d)(p, q, d))

1.3 RSA 核心性质

∀m∈Zn∗:(me)d≡med≡m(modn)\forall m \in \mathbb{Z}_n^*: \quad (m^e)^d \equiv m^{ed} \equiv m \pmod{n}

因为 ed≡1(modϕ(n))ed \equiv 1 \pmod{\phi(n)},所以 med=mkϕ(n)+1=(mϕ(n))k⋅m≡m(modn)m^{ed} = m^{k\phi(n)+1} = (m^{\phi(n)})^k \cdot m \equiv m \pmod{n}。

2. 朴素 RSA 签名(不安全!)

2.1 基本思路

Sign(sk,m):σ=md mod n\text{Sign}(sk, m): \quad \sigma = m^d \bmod n Verify(vk,m,σ):σe≡?m(modn)\text{Verify}(vk, m, \sigma): \quad \sigma^e \stackrel{?}{\equiv} m \pmod{n}

2.2 朴素 RSA 的攻击

存在性伪造:

  • 攻击者选 σ∗\sigma^*,计算 m∗=(σ∗)e mod nm^* = (\sigma^*)^e \bmod n
  • 得到合法的 (m∗,σ∗)(m^*, \sigma^*) 对,无需知道 sksk!

乘法可延展:

Sign(sk,m1)⋅Sign(sk,m2)=m1d⋅m2d=(m1m2)d=Sign(sk,m1m2) mod n\text{Sign}(sk, m_1) \cdot \text{Sign}(sk, m_2) = m_1^d \cdot m_2^d = (m_1 m_2)^d = \text{Sign}(sk, m_1 m_2) \bmod n

因此可组合已知签名伪造新签名。

3. RSA-FDH(Full Domain Hash)

3.1 方案

引入哈希函数 H:{0,1}∗→Zn∗H: \{0,1\}^* \to \mathbb{Z}_n^*:

Sign(sk,m):σ=H(m)d mod n\text{Sign}(sk, m): \quad \sigma = H(m)^d \bmod n Verify(vk,m,σ):σe≡?H(m)(modn)\text{Verify}(vk, m, \sigma): \quad \sigma^e \stackrel{?}{\equiv} H(m) \pmod{n}

3.2 安全性

  • 哈希先消除消息的结构,伪造需要对 H(m∗)H(m^*) 开 dd 次方
  • 在随机预言模型(Random Oracle Model, ROM)下,RSA-FDH 的 EUF-CMA 安全性可规约到 RSA 问题的难度

RSA 问题(RSA Assumption):给定 (n,e,y)(n, e, y),难以找 xx 使 xe≡y(modn)x^e \equiv y \pmod{n}。

4. RSA-PSS(实际标准)

RSA-PSS(Probabilistic Signature Scheme)是 PKCS#1 v2 标准,在随机预言模型下可证明安全:

签名

  1. 选随机盐 r \xleftarrow{\} {0,1}^\lambda$
  2. 计算 w=H(m∥r)w = H(m \| r)
  3. 从 w,rw, r 生成填充串(通过 MGF——Mask Generation Function)
  4. σ=(填充串)d mod n\sigma = (\text{填充串})^d \bmod n

验证

  1. 计算 σe mod n\sigma^e \bmod n,解析出 w′,r′w', r'
  2. 验证 w′=?H(m∥r′)w' \stackrel{?}{=} H(m \| r')

5. 椭圆曲线数字签名(ECDSA)

5.1 椭圆曲线 DLP

定义在素域 Fp\mathbb{F}_p 上的曲线 E:y2=x3+ax+bE: y^2 = x^3 + ax + b,取 nn 阶生成元 GG。

ECDLP:给定 Q=xG∈EQ = xG \in E(x∈Znx \in \mathbb{Z}_n),求 xx。

目前最好算法时间 ≈2n/2\approx 2^{n/2}(n=256n = 256 时 ≈2128\approx 2^{128}),比 RSA 效率更高。

5.2 密钥生成

sk=d←$Zn∗,vk=Q=dG∈Esk = d \xleftarrow{\$} \mathbb{Z}_n^*, \quad vk = Q = dG \in E

5.3 ECDSA 签名

k←$Zn∗,R=kG,r=Rx mod nk \xleftarrow{\$} \mathbb{Z}_n^*, \quad R = kG, \quad r = R_x \bmod n s=k−1(H(m)+dr) mod ns = k^{-1}(H(m) + dr) \bmod n σ=(r,s)\sigma = (r, s)

5.4 ECDSA 验证

u1=s−1H(m) mod n,u2=s−1r mod nu_1 = s^{-1} H(m) \bmod n, \quad u_2 = s^{-1} r \bmod n R′=u1G+u2QR' = u_1 G + u_2 Q 接受当且仅当 Rx′≡r(modn)\text{接受当且仅当 } R'_x \equiv r \pmod{n}

5.5 Nonce 重用漏洞

若同一 kk 被用于签名两条不同消息 m1,m2m_1, m_2:

s1=k−1(H(m1)+dr) mod ns_1 = k^{-1}(H(m_1) + dr) \bmod n s2=k−1(H(m2)+dr) mod ns_2 = k^{-1}(H(m_2) + dr) \bmod n

s1−s2=k−1(H(m1)−H(m2))⇒k=H(m1)−H(m2)s1−s2s_1 - s_2 = k^{-1}(H(m_1) - H(m_2)) \Rightarrow k = \frac{H(m_1) - H(m_2)}{s_1 - s_2}

然后可求 d=(s1k−H(m1))/r mod nd = (s_1 k - H(m_1)) / r \bmod n——私钥泄露!

2013 年 PlayStation 3 即因 kk 固定为常数被破解私钥。

6. Schnorr 签名(基于 Fiat-Shamir)

k←$Zq,R=gk,e=H(R∥m),s=k+ex mod qk \xleftarrow{\$} \mathbb{Z}_q, \quad R = g^k, \quad e = H(R \| m), \quad s = k + ex \bmod q σ=(R,s)\sigma = (R, s)

验证:gs=?R⋅yeg^s \stackrel{?}{=} R \cdot y^e(其中 y=gxy = g^x 为公钥)

优势:签名长度 2×32=642 \times 32 = 64 bytes(secp256k1),线性代数结构支持多重签名聚合(MuSig)。

7. RSA vs ECDSA vs Schnorr 对比

方案密钥大小签名大小安全基础
RSA-2048256 bytes256 bytes整数分解
ECDSA-25632 bytes64 bytesECDLP
Ed25519(Schnorr)32 bytes64 bytesECDLP

关键公式

RSA-FDH:

σ=H(m)d mod n,验证:σe≡H(m)(modn)\sigma = H(m)^d \bmod n, \quad \text{验证:} \sigma^e \equiv H(m) \pmod{n}

ECDSA 签名:

s=k−1(H(m)+dr) mod ns = k^{-1}(H(m) + dr) \bmod n

Schnorr(Fiat-Shamir):

e=H(R∥m), s=k+ex mod qe = H(R \| m),\ s = k + ex \bmod q 验证:gs=R⋅ye\text{验证:} g^s = R \cdot y^e

我的理解

签名编码和填充属于密码构造本身,而不是可随意更换的序列化细节;错误组合会让安全归约失效。