数字签名算法¶
数字签名方案¶
-
公钥签名方案:
-
利用私钥生成签名
-
利用公钥验证签名
-
-
只有私钥的拥有者才能生成签名,所以能够用于证明谁生成的消息
-
任何知道公钥的人可以验证消息(他们要确认公钥拥有者的身份,这是公钥的密钥分配问题)
-
通常不对整个消息签名,因为这将会使交换信息长度增加一倍
- 使用消息的 hash 值
-
数字签名可以 提供消息的不可否认性
RSA 签名方案¶
-
RSA 加密解密是可交换的
-
可以用于数字签名方案
RSA 密钥生成¶
-
选择两个大素数 \(p\) 和 \(q\)
-
计算 \(n = p \cdot q\)
-
计算 \(\phi(n) = (p - 1)(q - 1)\)
-
选择公钥指数 \(e\),满足 \(1 < e < \phi(n)\) 且 \(\gcd(e, \phi(n)) = 1\)
-
计算私钥指数 \(d\),满足 \(d \cdot e \equiv 1 \bmod \phi(n)\)
-
公钥是 \((e, n)\)
-
私钥是 \((d, p, q)\)
RSA 签名生成与验证¶
-
给定 RSA 方案 \(\{K=(e, n), K^{-1}=(d, p, q)\}\)
-
要签名消息 \(M\):计算:
\[ \begin{cases} h = H(M) \\ S = h^{d} (\bmod n) \\ \end{cases} \Rightarrow (M, S) \] -
要验证签名, 计算:
\[ \begin{cases} h = H(M) \\ h' = S^{e}(\bmod n) \\ \end{cases} \Rightarrow h^{\prime} = h? \]
-
RSA 签名方案的使用¶
-
使用 RSA 加密、认证:
-
假设 A 发送消息给 B
-
用发送者的私钥签名:\(S = M^{d_A} \bmod n_A\)
-
用接收者的公钥加密:\(C = S^{e_B} \bmod n_B\)
-
-
接收者 B 解密:
-
\(S = C^{d_B} \bmod n_B\)
-
验证签名:\(M = S^{e_A} \bmod n_A\)
-
-
-
看起来,一个消息可用 RSA 先加密再签名而不改变大小
-
但是,加密使用的是消息接收者的模,签名是消息发送者的模,后者可能比前者小
-
如果先加密再签名,可能会导致加密后的消息大于签名模,无法使用 RSA 进行签名(RSA 要求 \(0 < M < n\))
-
交换两者顺序,先签名再加密可以避免这个问题
-
-
签名常使用 HASH 函数值
- 用 \(h=H(M)\) 代替消息 \(M\) 进行签名
ElGamal 签名方案¶
-
ElGamal 加密算法是不可交换的
-
存在一个相关的签名算法
-
安全性是 基于计算离散对数的困难性
ElGamal 密钥生成¶
-
选择共享的素数 \(p\) 和公开的生成元 \(g\)
-
每个用户选择一个随机数作为私钥 \(x\)
-
计算各自的公开密钥:\(y = g^x \bmod p\)
-
公钥是 \((y, g, p)\)
-
私钥是 \((x)\)
ElGamal 签名生成与验证¶
-
签名消息 \(M\):
-
选择随机数 \(k\),满足 \(\gcd(k, p - 1) = 1\)
- \(k\) 应该被销毁或保密,不能重复使用
-
计算 \(K = g^{k} \bmod p\)
-
用 Euclidean (inverse) 扩展算法求 \(S\):
-
\(M = x \cdot K + k \cdot S \bmod (p - 1)\) ;
-
即求 \(S = k^{-1}(M - x \cdot K) \bmod (p - 1)\)
-
-
发送 \((M, K, S)\),其中 \((K, S)\) 是对 \(M\) 的签名
-
-
验证 \((K, S)\) 是对 \(M\) 的签名:
- \(y^{K} \cdot K^{S} \equiv g^{M} \bmod p\)
-
同 ElGamal 加密方案,签名信息也是消息的 2 倍
- 通常对消息的 HASH 值进行签名
ElGamal 签名方案举例¶
-
密钥生成:
-
取 \(p = 11, g = 2\)
-
选择私钥 \((x = 8)\)
-
计算公钥:
-
\(y = g^x \bmod p = 2^8 \bmod 11 = 3\)
-
公钥是 \((y = 3, g = 2, p = 11)\)
-
-
-
对 \(M = 5\) 签名:
-
选择随机数 \(k = 9\)
-
确定 \(\gcd(9, 10) = 1\)
-
计算:\(K = g^{k} \bmod p = 2^9 \bmod 11 = 6\)
-
求解:
\[ 5 = 8 \times 6 + 9 \cdot S \bmod 10; \]-
因为 \(9^{-1} \equiv 9 \bmod 10\)
-
所以 \(S = k^{-1}(M - x \cdot K) \bmod (p - 1) = 9 \times (5 - 8 \times 6) \bmod 10 = 3\)
-
-
签名是 \((K = 6, S = 3)\)
-
-
要验证签名,确认:
\[ \begin{aligned} &y^{K} \cdot K^{S} \bmod p = 3 ^ {6} \cdot 6 ^ {3} \bmod 11 = 10 \\ &g^{M} \bmod p = 2 ^ {5} \bmod 11 = 10 \\ \end{aligned} \]
DSA (Digital Signature Algorithm)¶
-
DSA 是数字签名算法,DSS 是数字签名标准
-
DSA 是 ElGamal 及 Schnorr algorithms 的变形
-
生成 320 bit 签名
-
安全性是 基于计算离散对数的困难性
-
被广泛接受
DSA 密钥生成¶
-
首先选取公开参数 \((p, q, g)\):
-
选取大素数 \(p\)
- 512 ~ 1024 bit(64 倍数)
-
选取素数 \(q\)
-
160 bit
-
\(q\) 是 \(p - 1\) 的因子
-
-
选择 \(g = h^{(p - 1) / q}\)
- 满足对任何 \(h < p - 1, h^{(p - 1) / q} \pmod p > 1\)
-
-
每个用户选取私钥并计算他们的公钥:
-
选取 \(x < q\)
-
计算 \(y = g^{x} \bmod p\)
-
公钥是 \((y, p, q, g)\)
-
私钥是 \((x)\)
-
DSA 签名生成与验证¶
-
签名消息 \(M\)
-
生成随机签名密钥 \(k\),满足 \(k < q\)
-
计算
\[ \begin{aligned} &K = (g^{k} \bmod p) \bmod q \\ &S = k^{-1} \cdot (\mathrm{HASH}(M) + x \cdot K) \pmod{q} \end{aligned} \]
-
-
发送签名 \((K, S)\) 及消息 \(M\)
-
验证签名, 计算:
\[ \begin{cases} w = S^{-1} \pmod{q} \\ u1 = (\mathrm{HASH}(M)\cdot w) \pmod{q} \\ u2 = K\cdot w \pmod{q} \\ v = g^{u1}\cdot y^{u2} \pmod{p}\pmod{q} \\ \end{cases}\quad \Rightarrow v = K? \]
DSA 安全性¶
-
基于离散对数
-
最初建议使用一个共同的 modulus p
-
现在建议不同的工作组使用不同的 \((p, q, g)\)
-
Gus Simmons 发现存在潜信道,能够泄露私钥
带密钥的 HASH¶
-
以上的签名方法都是公钥技术
- 计算与数据量较大
-
需要私钥的认证方案
-
好的方法是使用快速的 hash 函数:
-
密钥与消息同时参加运算:
\[ KeyedHash = \mathbf{Hash}(Key \parallel Message) \] -
存在一些弱点
-
-
随后建议:
\[ KeyedHash = \mathbf{Hash} (Key_1 \parallel \mathbf{Hash} (Key_2 \parallel Message)) \]
HMAC¶
-
HMAC 是使用带密钥的 HASH 函数的结果
-
成为 internet 标准(RFC2104)
-
结构:
\[ HMAC_K = \mathbf{Hash}((K^+ \oplus opad) \parallel \mathbf{Hash}((K^+ \oplus \text{ipad}) \parallel M)) \]-
\(K^+\):经过填充的密钥
-
\(opad, ipad\):特殊的填充值
-
\(opad=01011010\) 重复 \(b/8\) 次
-
\(ipad=00110110\) 重复 \(b/8\) 次
-
-
-
安全性是基于原来的 HASH 函数的安全性
-
任何 MD5, SHA-1, RIPEMD-160 都可以这样使用