9 数字签名
-
本节学习公钥密码学中用于保护信息完整性和真实性的数字签名。
-
目录:数字签名定义、RSA签名、来自离散对数问题的数字签名、一次签名方案、证书与公钥基础设施。
-
数字签名概览
- 数字签名(Digital signature)是一个数学方案用来证明一个数字消息的真实性/完整性。
- 数字签名允许一个签名者(Signer) S S S 用其自己的私钥来“签名”(sign)一个消息,并且任何知道 S S S 的公钥的人可以验证(verify)其真实性/完整性。
- 与MAC相比,数字签名是:
- 公开可验证的(publicily verifiable);
- 可转移的(transferable);
- 不可抵赖(non-repudiation);
- 但速度慢。
- 问题:数字签名和手写签名的却别是什么?
- 数字签名不是公钥加密的逆。
-
数字签名方案词法
- 签名 σ \sigma σ, 比特 b b b 表示有效( v a l i d \mathsf{valid} valid)如果 b = 1 b=1 b=1; 无效( i n v a l i d \mathsf{invalid} invalid)如果 b = 0 b=0 b=0。
- 密钥生成算法(Key-generation): ( p k , s k ) ← G e n ( 1 n ) , ∣ p k ∣ , ∣ s k ∣ ≥ n (pk,sk) \gets \mathsf{Gen}(1^n), |pk|,|sk| \ge n (pk,sk)←Gen(1n),∣pk∣,∣sk∣≥n。
- 签名(Signing)算法: σ ← S i g n s k ( m ) \sigma \gets \mathsf{Sign}_{sk}(m) σ←Signsk(m)。
- 验证(Verification)算法: b : = V r f y p k ( m , σ ) b:= \mathsf{Vrfy}_{pk}(m,\sigma) b:=Vrfypk(m,σ)。
- 基本正确性要求: V r f y p k ( m , S i g n s k ( m ) ) = 1 \mathsf{Vrfy}_{pk}(m,\mathsf{Sign}_{sk}(m)) = 1 Vrfypk(m,Signsk(m))=1。
-
定义签名安全
- 安全数字签名定义与安全MAC类似,敌手难以伪造一个“新消息”的签名。
- 签名实验
S
i
g
f
o
r
g
e
A
,
Π
(
n
)
\mathsf{Sigforge}_{\mathcal{A},\Pi }(n)
SigforgeA,Π(n):
- 挑战者生成密钥对 ( p k , s k ) ← G e n ( 1 n ) (pk,sk) \gets \mathsf{Gen}(1^n) (pk,sk)←Gen(1n)。
- 敌手 A \mathcal{A} A 给予输入 1 n 1^n 1n 以及对签名预言机的访问 S i g n s k ( ⋅ ) \mathsf{Sign}_{sk}(\cdot) Signsk(⋅),然后输出 ( m , σ ) (m,\sigma) (m,σ)。 Q \mathcal{Q} Q 是对预言机的查询的集合。
- 实验成功 S i g f o r g e A , Π ( n ) = 1 ⟺ \mathsf{Sigforge}_{\mathcal{A},\Pi }(n)=1 \iff SigforgeA,Π(n)=1⟺ V r f y p k ( m , σ ) = 1 \mathsf{Vrfy}_{pk}(m,\sigma)=1 Vrfypk(m,σ)=1 ∧ \land ∧ m ∉ Q m \notin \mathcal{Q} m∈/Q.
- 一个签名方案 Π \Pi Π 是在适应性选择消息攻击下的存在性不可伪造(existentially unforgeable under an adaptive CMA),如果 ∀ \forall ∀ PPT A \mathcal{A} A, ∃ \exists ∃ n e g l \mathsf{negl} negl 使得: Pr [ S i g f o r g e A , Π ( n ) = 1 ] ≤ n e g l ( n ) . \Pr [\mathsf{Sigforge}_{\mathcal{A},\Pi }(n)=1] \le \mathsf{negl}(n). Pr[SigforgeA,Π(n)=1]≤negl(n).
- 问题:在MAC和数字签名中敌手能力的差别是什么?如果敌手不限制算力为PPT会如何?
-
“书本上RSA”的不安全性
- 构造:
- G e n \mathsf{Gen} Gen: on input 1 n 1^n 1n run G e n R S A ( 1 n ) \mathsf{GenRSA}(1^n) GenRSA(1n) to obtain N , e , d N,e,d N,e,d. p k = ⟨ N , e ⟩ pk = \langle N,e \rangle pk=⟨N,e⟩ and s k = ⟨ N , d ⟩ sk = \langle N,d \rangle sk=⟨N,d⟩.
- S i g n \mathsf{Sign} Sign: on input s k sk sk and m ∈ Z N ∗ m \in \mathbb{Z}^*_N m∈ZN∗, σ : = [ m d m o d N ] \sigma:= [m^d \bmod N] σ:=[mdmodN].
- V r f y \mathsf{Vrfy} Vrfy: on input p k pk pk and m ∈ Z N ∗ m \in \mathbb{Z}^*_N m∈ZN∗, m = ? [ σ e m o d N ] m \overset{?}{=} [\sigma^e \bmod N] m=?[σemodN].
- 无消息攻击(no-message attack):
- 选择一个任意 σ ∈ Z N ∗ \sigma \in \mathbb{Z}^*_N σ∈ZN∗ 并且计算 m : = [ σ e m o d N ] m := [\sigma^e \bmod N] m:=[σemodN]。输出伪造签名 ( m , σ ) (m,\sigma) (m,σ)。
- 例子: p k = < 15 , 3 > , σ = 2 , m = ? m d = ? pk = \left<15, 3\right>,\ \sigma = 2,\ m = ?\ m^{d} = ? pk=⟨15,3⟩, σ=2, m=? md=?
- 任意消息攻击(Forging a signature on an arbitrary message):为了伪造
m
m
m 的签名,选择一个随机的
m
1
m_1
m1,令
m
2
:
=
[
m
/
m
1
m
o
d
N
]
m_2 := [m/m_1 \bmod N]
m2:=[m/m1modN],查询预言机获得消息
m
1
,
m
2
m_1, m_2
m1,m2 的签名
σ
1
,
σ
2
\sigma_1, \sigma_2
σ1,σ2 。
- 问题: σ : = [ ‾ m o d N ] \sigma := [\underline{\qquad} \bmod N] σ:=[modN] 是 m m m 的一个有效签名。
- 构造:
-
哈希(Hashed)RSA签名
- 思路:用哈希函数来打破消息和签名之间的的强代数关系
- RSA-FDH 签名方案:随机预言机作为一个全域哈希(Full Domain Hash,FDH)),其定义域大小为 RSA 的模数 N − 1 N-1 N−1。(PKCS #1 v2.1)
- 目前实际使用哈希RSA数字签名方案:
- G e n \mathsf{Gen} Gen: 一个哈希函数 H : { 0 , 1 } ∗ → Z N ∗ H : \{0,1\}^* \to \mathbb{Z}_N^* H:{0,1}∗→ZN∗ 作为公钥的一部分。
- S i g n \mathsf{Sign} Sign: σ : = [ H ( m ) d m o d N ] \sigma := [H(m)^d \bmod N] σ:=[H(m)dmodN].
- V r f y \mathsf{Vrfy} Vrfy: σ e = ? H ( m ) m o d N \sigma^e \overset{?}{=} H(m) \bmod N σe=?H(m)modN.
- 如果 H H H 无法有效求逆,那么无消息攻击和伪造任意消息的签名都是难的。
- 无消息攻击:敌手无法求逆
- 任意消息攻击: σ 2 \sigma_2 σ2 与 σ \sigma σ没有关系
- 不安全性:没有已知函数 H H H 使得哈希RSA签名是安全的。
“哈希签名”范式
- 将消息哈希后再签名可以实现安全的数字签名。
-
Π
=
(
G
e
n
S
,
S
i
g
n
,
V
r
f
y
)
\Pi = (\mathsf{Gen}_S, \mathsf{Sign}, \mathsf{Vrfy})
Π=(GenS,Sign,Vrfy),
Π
H
=
(
G
e
n
H
,
H
)
\Pi_H = (\mathsf{Gen}_H, H)
ΠH=(GenH,H). 一个签名方案
Π
′
\Pi'
Π′:
- G e n ′ \mathsf{Gen}' Gen′: 输入 1 n 1^n 1n 运行 G e n S ( 1 n ) \mathsf{Gen}_S(1^n) GenS(1n) 来得到 ( p k , s k ) (pk,sk) (pk,sk), 并且运行 G e n H ( 1 n ) \mathsf{Gen}_H(1^n) GenH(1n) 来得到 s s s。 公钥是 p k ′ = ⟨ p k , s ⟩ pk'=\langle pk,s\rangle pk′=⟨pk,s⟩ 并且私钥是 s k ′ = ⟨ s k , s ⟩ sk' = \langle sk,s\rangle sk′=⟨sk,s⟩。
- S i g n ′ \mathsf{Sign}' Sign′: 输入 s k ′ sk' sk′ 并且 m ∈ { 0 , 1 } ∗ m \in \{0,1\}^* m∈{0,1}∗, σ ← S i g n s k ( H s ( m ) ) \sigma \gets \mathsf{Sign}_{sk}(H^s(m)) σ←Signsk(Hs(m))。
- V r f y ′ \mathsf{Vrfy}' Vrfy′: 输入 p k ′ pk' pk′, m ∈ { 0 , 1 } ∗ m \in \{0,1\}^* m∈{0,1}∗ 并且 σ \sigma σ, 输出 1 ⟺ \iff ⟺ V r f y p k ( H s ( m ) , σ ) = 1 \mathsf{Vrfy}_{pk}(H^s(m),\sigma)=1 Vrfypk(Hs(m),σ)=1。
- 定理:如果 Π \Pi Π 是在适应性CMA下的存在性不可伪造,并且 Π H \Pi_H ΠH 是抗碰撞,那么构造是适应性CMA下的存在性不可伪造。
- 证明:敌手无法实施之前的“无消息攻击”和“伪造任意消息签名攻击”。敌手的成功需要发现哈希碰撞,或者针对 Π \Pi Π伪造签名。
-
Schnorr签名概览
- Schnorr签名展现了签名,身份识别和零知识证明之间的联系
- 该方案是Schnorr身份识别协议的非交互版本,而后者是一个对离散对数问题的解的交互式零知识证明
- 安全:在ROM下和离散对数难题假设下,将Fiat-Shamir变换应用于Schnorr身份识别协议
- 应用于多重签名,门限签名和盲签名,这些技术被广泛应用于密码学货币
身份认证(Identification)方案
- 下面学习Schnorr身份认证方案,该方案可以用于构造基于离散对数问题的Schnorr数字签名方案。
- 身份认证(identification)方案 Π = ( G e n , P 1 , P 2 , V ) \Pi = (\mathsf{Gen}, \mathcal{P}_1, \mathcal{P}_2, \mathcal{V}) Π=(Gen,P1,P2,V) 是一个在证明者(prover)和验证者(verifier)之间的三轮协议。其中,证明者运行 P 1 , P 2 \mathcal{P}_1, \mathcal{P}_2 P1,P2两个算法,验证者运行 V \mathcal{V} V算法。
- 证明者说服验证者其是一个公钥所对应的私钥的持有者,通过“知道什么”来证明自己的身份。
- 敌手能够窃听并且可以通过作为一个验证者来访问一个预言机 T r a n s s k \mathsf{Trans}_{sk} Transsk 来获得信息 ( I , r , s ) (I, r, s) (I,r,s) ,即真的证明者与敌手(作为验证者)间执行身份认证协议。
- 公开可验证:除了证明者和验证者之外,其他人也可以根据传递的消息来验证证明者的身份!
- 身份认证协议:
- 证明者生成 ( I , s t ) ← P 1 ( s k ) (I, \mathsf{st})\gets \mathcal{P}_1(sk) (I,st)←P1(sk),并将 I I I发送给验证者。注:这里不能泄漏关于私钥的信息,并且这个 I I I可用于保护私钥。
- 验证者生成 r ← Ω p k r \gets \Omega_{pk} r←Ωpk,并将 r r r发送给证明者。注:挑战信息不能被证明者预知,否则证明者有可能在不知道私钥的情况下伪装自己
- 证明者生成 s : = P 2 ( s k , s t , r ) s := \mathcal{P}_2(sk, \mathsf{st}, r) s:=P2(sk,st,r),并将 s s s发送给证明者。注:证明者对挑战作出响应,必然要用到自己的私钥,但不能让验证者推断出私钥
- 验证者验证 V ( p k , r , s ) = ? I \mathcal{V}(pk, r, s) \overset{?}{=} I V(pk,r,s)=?I。注:确定只有私钥的持有者能通过验证
- 其中, s t \mathsf{st} st 表示证明者维护的状态信息。
身份认证方案安全定义
-
思路:敌手能够作为验证者进行实验,但仍不能自己伪装成证明者。
-
身份认证实验 I d e n t A , Π ( n ) \mathsf{Ident}_{\mathcal{A},\Pi }(n) IdentA,Π(n):
- 证明者生成密钥对, ( p k , s k ) ← G e n ( 1 n ) (pk,sk) \gets \mathsf{Gen}(1^n) (pk,sk)←Gen(1n).
- 敌手 A \mathcal{A} A 给予输入 1 n 1^n 1n 和对 T r a n s s k ( ⋅ ) \mathsf{Trans}_{sk}(\cdot) Transsk(⋅) 的预言机访问,输出一个消息 I I I。
- 挑战者挑选一个均匀的挑战 r r r 并将其发送给 A \mathcal{A} A,然后敌手 A \mathcal{A} A 输出 s s s。 ( A \mathcal{A} A 可以继续查询预言机。)
- 实验成功如果验证成功, I d e n t A , Π ( n ) = 1 ⟺ V ( p k , r , s ) = ? I \mathsf{Ident}_{\mathcal{A},\Pi }(n) = 1 \iff \mathcal{V}(pk, r, s) \overset{?}{=} I IdentA,Π(n)=1⟺V(pk,r,s)=?I。-
-
定义:一个身份认证方案 Π = ( G e n , P 1 , P 2 , V ) \Pi = (\mathsf{Gen}, \mathcal{P}_1, \mathcal{P}_2, \mathcal{V}) Π=(Gen,P1,P2,V) 是安全的,如果 ∀ \forall ∀ PPT A \mathcal{A} A, ∃ \exists ∃ n e g l \mathsf{negl} negl 使得:
Pr [ I d e n t A , Π ( n ) = 1 ] ≤ n e g l ( n ) . \Pr [\mathsf{Ident}_{\mathcal{A},\Pi }(n) = 1] \le \mathsf{negl}(n). Pr[IdentA,Π(n)=1]≤negl(n).
-
Schnorr身份认证方案
- 证明者公开地证明其知道一个离散对数问题的解,通过一个三轮的西格玛协议
- 证明者持有一个离散对数问题
g
x
=
y
g^x = y
gx=y的私钥部分
x
x
x,生成
k
←
Z
q
k \gets \mathbb{Z}_q
k←Zq;
I
:
=
g
k
I := g^k
I:=gk,并将
I
I
I发送给验证者。
- 注:这个 k k k就是 s t \mathsf{st} st, 后面用来隐藏私钥 x x x;
- 验证者生成
r
←
Z
q
r \gets \mathbb{Z}_q
r←Zq,并将
r
r
r发送给证明者。
- 注:随机的 r r r不能被预测,并且在 I I I之后产生;
- 证明者生成
s
:
=
[
r
x
+
k
m
o
d
q
]
s := [rx + k \mod q]
s:=[rx+kmodq],并将
s
s
s发送给证明者。
- 注:用 x x x生成应答,并用 k k k隐藏 x x x;
- 验证者验证 V ( p k , r , s ) = g s ⋅ y − r = ? I \mathcal{V}(pk, r, s) = g^s \cdot y^{-r} \overset{?}{=} I V(pk,r,s)=gs⋅y−r=?I。注: g s ⋅ y − r = g r x + k g − r x = g k g^s \cdot y^{-r} = g^{rx+k} g^{-rx} = g^k gs⋅y−r=grx+kg−rx=gk
- 证明者持有一个离散对数问题
g
x
=
y
g^x = y
gx=y的私钥部分
x
x
x,生成
k
←
Z
q
k \gets \mathbb{Z}_q
k←Zq;
I
:
=
g
k
I := g^k
I:=gk,并将
I
I
I发送给验证者。
- 问题:为什么一个更简单的协议不安全?
- 证明者公开地证明其知道一个离散对数问题的解,通过一个三轮的西格玛协议
-
Schnorr身份认证方案证明
- 定理:如果离散对数是难的,那么Schnorr身份认证方案是安全的。
- 思路:如果攻击身份认证方案的敌手可以成功使得 g s ⋅ y − r = I g^s \cdot y^{-r} = I gs⋅y−r=I,那么离散对数问题可以被解决。
- 证明:将求
y
y
y的逆的算法
A
′
\mathcal{A}'
A′ 规约到攻击Schnorr方案的
A
\mathcal{A}
A:
- A ′ \mathcal{A}' A′ 作为验证者并运行 A \mathcal{A} A 作为证明者, A ′ \mathcal{A}' A′回答 A \mathcal{A} A的查询。
- 当 A \mathcal{A} A 输出 I I I, A ′ \mathcal{A}' A′ 选择 r 1 ∈ Z q r_1 \in \mathbb{Z}_q r1∈Zq 并且发送给 A \mathcal{A} A,后者以 s 1 s_1 s1 应答。
- 再一次运行 A \mathcal{A} A ,将 r 2 ∈ Z q r_2 \in \mathbb{Z}_q r2∈Zq 发送给 A \mathcal{A} A ,后者其应答 s 2 s_2 s2。
- 如果 g s 1 ⋅ h − r 1 = I g^{s_1} \cdot h^{-r_1} = I gs1⋅h−r1=I 并且 g s 2 ⋅ h − r 2 = I g^{s_2} \cdot h^{-r_2} = I gs2⋅h−r2=I 并且 r 1 ≠ r 2 r_1 \neq r_2 r1=r2 那么输出 x = [ ( s 1 − s 2 ) ⋅ ( r 1 − r 2 ) − 1 m o d q ] x = [ (s_1 - s_2)\cdot (r_1 - r_2)^{-1} \mod q] x=[(s1−s2)⋅(r1−r2)−1modq],否则输出空。
Fiat-Shamir变换
- Fiat-Shamir变换通过签名者自己运行身份认证协议来构造一个(非交互)的签名方案。如果签名可以被伪造,那么意味着身份可以伪造。
- 令
Π
=
(
G
e
n
i
d
,
P
1
,
P
2
,
V
)
\Pi = (\mathsf{Gen}_{\mathsf{id}}, \mathcal{P}_1, \mathcal{P}_2, \mathcal{V})
Π=(Genid,P1,P2,V) 为一个身份识别方案,签名方案构造如下:
- G e n \mathsf{Gen} Gen: ( p k , s k ) ← G e n i d (pk, sk) \gets \mathsf{Gen}_{\mathsf{id}} (pk,sk)←Genid。一个函数 H : { 0 , 1 } ∗ → Ω p k H : \{0,1\}^* \to \Omega_{pk} H:{0,1}∗→Ωpk (挑战集).
-
S
i
g
n
\mathsf{Sign}
Sign: 输入
s
k
sk
sk 并且
m
∈
{
0
,
1
}
∗
m \in \{0,1\}^*
m∈{0,1}∗;
- 计算 ( I , s t ) ← P 1 ( s k ) (I, \mathsf{st}) \gets \mathcal{P}_1(sk) (I,st)←P1(sk)
- 计算 r : = H ( I , m ) r := H(I, m) r:=H(I,m) 注:此处引入随机预言机来得到消息的指纹
- 计算 s : = P 2 ( s k , s t , r ) s := \mathcal{P}_2(sk, \mathsf{st}, r) s:=P2(sk,st,r) 注:消息的指纹和私钥一起生成签名
- 输出签名 r , s r, s r,s。注:签名是概率性的
- V r f y \mathsf{Vrfy} Vrfy: 计算 I : = V ( p k , r , s ) I := \mathcal{V}(pk, r, s) I:=V(pk,r,s),并且输出 1 ⟺ H ( I , m ) = ? r 1 \iff H(I, m) \overset{?}{=} r 1⟺H(I,m)=?r。注:
- 定理:如果 Π \Pi Π 是一个安全身份认证方案,并且 H H H 是随机预言机,那么 Fiat-Shamir 变换会得到一个安全签名方案。
- 证明:大致思路是, r r r与消息通过 H H H绑定,改变消息会得到一个新的随机的 r r r。将身份认证方案的敌手算法规约到签名方案的敌手算法。如果签名可以被伪造,那么意味着身份可以伪造。
-
Schnorr签名方案
- 根据Fiat-shamir变换,可以用Schnorr身份认证方案来构造数字签名方案,签名者自己运行身份识别协议
- G e n \mathsf{Gen} Gen: ( G , q , g ) ← G ( 1 n ) (\mathcal{G}, q, g) \gets \mathcal{G}(1^n) (G,q,g)←G(1n)。选择 x ∈ Z q x \in \mathbb{Z}_q x∈Zq 并且令 y : = g x y := g^x y:=gx。私钥为 x x x 而公钥为 ( G , q , g , y ) (\mathcal{G}, q, g, y) (G,q,g,y)。一个函数 H : { 0 , 1 } ∗ → Z q H : \{0,1\}^* \to \mathbb{Z}_q H:{0,1}∗→Zq。
-
S
i
g
n
\mathsf{Sign}
Sign: 输入
x
x
x 和
m
∈
{
0
,
1
}
∗
m \in \{0,1\}^*
m∈{0,1}∗,执行以下操作
- 计算 I : = g k I := g^k I:=gk, 其中一个均匀的 k ∈ Z q k \in \mathbb{Z}_q k∈Zq;
- 计算 r : = H ( I , m ) r := H(I, m) r:=H(I,m);
- 计算 s : = [ r x + k m o d q ] s := [ rx + k \mod q] s:=[rx+kmodq];
- 输出签名 ( r , s ) (r, s) (r,s)。
- V r f y \mathsf{Vrfy} Vrfy: 计算 I : = g s ⋅ y − r I := g^s \cdot y^{-r} I:=gs⋅y−r 并且输出 1 ⟺ H ( I , m ) = ? r 1 \iff H(I, m) \overset{?}{=} r 1⟺H(I,m)=?r。
- 根据Fiat-shamir变换,可以用Schnorr身份认证方案来构造数字签名方案,签名者自己运行身份识别协议
-
DSS/DSA(数字签名标准/算法)
- NIST从1994年到2013年颁布的数字签名标准(Digital Signature Standard,DSS) 使用数字签名算法(Digital Signature Algorithm,DSA),该算法是一个ElGamal签名方案的变体。DSS中还包括椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm,ECDSA)和 RSA签名算法。
- 这两种算法基于相同的算法抽象:基于身份认证方案的签名方案。
- 构造:
- G e n \mathsf{Gen} Gen: ( G , q , g ) ← G (\mathbb{G},q,g) \gets \mathcal{G} (G,q,g)←G. 两个哈希函数 H , F : { 0 , 1 } ∗ → Z q H, F : \{0,1\}^* \to \mathbb{Z}_q H,F:{0,1}∗→Zq.
- x ← Z q x \gets \mathbb{Z}_q x←Zq 和 y : = g x y:= g^x y:=gx.
- p k = ⟨ G , q , g , y , H , F ⟩ pk = \langle \mathbb{G},q,g,y,H,F\rangle pk=⟨G,q,g,y,H,F⟩. s k = ⟨ G , q , g , x , H , F ⟩ sk=\langle \mathbb{G},q,g,x,H,F\rangle sk=⟨G,q,g,x,H,F⟩.
- S i g n \mathsf{Sign} Sign: k ← Z q ∗ k\gets \mathbb{Z}^*_q k←Zq∗ 并且 r : = F ( g k ) r:= F(g^k) r:=F(gk), s : = ( H ( m ) + x r ) ⋅ k − 1 s:= (H(m)+xr)\cdot k^{-1} s:=(H(m)+xr)⋅k−1. 输出 ( r , s ) (r,s) (r,s).
- V r f y \mathsf{Vrfy} Vrfy: 输出 1 ⟺ r = ? F ( g H ( m ) ⋅ s − 1 y r ⋅ s − 1 ) . 1 \iff r \overset{?}{=} F(g^{H(m)\cdot s^{-1}}y^{r\cdot s^{-1}}). 1⟺r=?F(gH(m)⋅s−1yr⋅s−1).
- DSA中验证的正确性?
-
DSS/DSA安全性
- 不安全性:DSS的安全性依赖于离散对数问题的难解性,尚未有基于离散对数假设的DSS安全性证明。
- k k k 的熵、保密和唯一性是安全性的关键。
- 情况1:如果 k k k是可预测的,那么 x x x将泄漏,因为 s : = ( H ( m ) + x r ) ⋅ k − 1 s:= (H(m)+xr)\cdot k^{-1} s:=(H(m)+xr)⋅k−1中只有 x x x是未知的。
- 情况2:如果同一个
k
k
k被用于同一私钥下的两个不同签名,那么
k
k
k和
x
x
x都将泄漏。问题:如何做?
- 该攻击曾在2010年用于对Sony PlayStation (PS3) 提取私钥。
-
一次签名(OTS)
-
下面学习不基于数论假设,而是基于哈希函数来构造安全的数字签名方案。
-
一次签名(One-Time Signature,OTS): 在一种较弱的攻击场景下,一个秘密只用于一个消息签名。
-
模拟一次签名场景,敌手最多只允许查询一次签名预言机,之后需要给出新消息和签名。
-
OTS实验 S i g f o r g e A , Π 1-time ( n ) \mathsf{Sigforge}_{\mathcal{A},\Pi }^{\text{1-time}}(n) SigforgeA,Π1-time(n):
- ( p k , s k ) ← G e n ( 1 n ) (pk,sk) \gets \mathsf{Gen}(1^n) (pk,sk)←Gen(1n).
- A \mathcal{A} A 输入 1 n 1^n 1n 和对 S i g n s k ( ⋅ ) \mathsf{Sign}_{sk}(\cdot) Signsk(⋅)的一次查询 m ′ m' m′ ,并且输出 ( m , σ ) (m,\sigma) (m,σ), m ≠ m ′ m \neq m' m=m′。
- S i g f o r g e A , Π 1-time ( n ) = 1 ⟺ V r f y p k ( m , σ ) = 1 \mathsf{Sigforge}_{\mathcal{A},\Pi }^{\text{1-time}}(n)=1 \iff \mathsf{Vrfy}_{pk}(m,\sigma)=1 SigforgeA,Π1-time(n)=1⟺Vrfypk(m,σ)=1.
-
一个签名方案 Π \Pi Π 在单个消息攻击下是存在性不可伪造的,如果 ∀ \forall ∀ PPT A \mathcal{A} A, ∃ \exists ∃ n e g l \mathsf{negl} negl 使得:
Pr [ S i g f o r g e A , Π 1-time ( n ) = 1 ] ≤ n e g l ( n ) . \Pr [\mathsf{Sigforge}_{\mathcal{A},\Pi }^{\text{1-time}}(n)=1] \le \mathsf{negl}(n). Pr[SigforgeA,Π1-time(n)=1]≤negl(n).
-
-
Lamport的OTS (1979)
- 思路:从单向函数构造OTS;每个比特为一个映射 。
- 构造:
- f f f 是一个OWF。抗碰撞哈希函数也是属于OWF。
-
G
e
n
\mathsf{Gen}
Gen: 输入
1
n
1^n
1n,对于
i
∈
{
1
,
…
,
ℓ
}
i \in \{1,\dotsc, \ell\}
i∈{1,…,ℓ}:
- 选择随机的两个函数输入 x i , 0 , x i , 1 ← { 0 , 1 } n x_{i,0}, x_{i,1} \gets \{0,1\}^n xi,0,xi,1←{0,1}n;
- 计算 y i , 0 : = f ( x i , 0 ) y_{i,0} := f(x_{i,0}) yi,0:=f(xi,0) 和 y i , 1 : = f ( x i , 1 ) y_{i,1} := f(x_{i,1}) yi,1:=f(xi,1)。
- 构成2个2xn的矩阵, x i , j x_{i,j} xi,j构成的矩阵是私钥, y i , j y_{i,j} yi,j构成的矩阵是公钥。
- S i g n \mathsf{Sign} Sign: m = m 1 ⋯ m ℓ m = m_1\cdots m_{\ell} m=m1⋯mℓ, 输出 σ = ( x 1 , m 1 , … , x ℓ , m ℓ ) \sigma = (x_{1,m_1},\dotsc,x_{\ell,m_{\ell}}) σ=(x1,m1,…,xℓ,mℓ)。根据消息中每个比特的值(0或1)来选择 x i , j x_{i,j} xi,j,得到的一个向量为签名。
- V r f y \mathsf{Vrfy} Vrfy: σ = ( x 1 , … , x ℓ ) \sigma = (x_1,\dotsc,x_{\ell}) σ=(x1,…,xℓ),输出 1 ⟺ 1 \iff 1⟺ 对于所有 i i i, f ( x i ) = y i , m i f(x_i) = y_{i,m_i} f(xi)=yi,mi。对消息的每个比特
- 定理:如果 f f f 是 OWF, Π \Pi Π 是长度为 ℓ \ell ℓ 的消息的OTS。
-
Lamport的OTS例子
- 略
-
Lamport的OTS安全性证明
- 思路:如果 m ≠ m ′ m \neq m' m=m′,那么 ∃ i ∗ , m i ∗ = b ∗ ≠ m i ∗ ′ \exists i^*, m_{i*} = b^* \neq m'_{i*} ∃i∗,mi∗=b∗=mi∗′。因此,为了伪造一个消息至少要对一个 y i ∗ , b ∗ y_{i^*,b^*} yi∗,b∗求逆。
- 证明:将对
y
y
y求逆的
I
\mathcal{I}
I 算法规约到攻击
Π
\Pi
Π的
A
\mathcal{A}
A 算法:
-
I
\mathcal{I}
I算法构造
p
k
pk
pk:选择
i
∗
←
{
1
,
…
,
ℓ
}
i^* \gets \{1,\dotsc,\ell\}
i∗←{1,…,ℓ} 并且
b
∗
←
{
0
,
1
}
b^* \gets \{0,1\}
b∗←{0,1},令
y
i
∗
,
b
∗
:
=
y
y_{i^*,b^*} := y
yi∗,b∗:=y。对于
i
≠
i
∗
i \neq i^*
i=i∗
y
i
,
b
:
=
f
(
x
i
,
b
)
y_{i,b} := f(x_{i,b})
yi,b:=f(xi,b);
- 在公钥中随机选择一个位置 ( i ∗ , b ∗ ) (i^*,b^*) (i∗,b∗),将待求逆的 y y y放在该位置;对于其它位置,正常构造公私钥对。
-
A
\mathcal{A}
A算法查询
m
′
m'
m′:如果
m
i
∗
′
=
b
∗
m_{i_*}' = b^*
mi∗′=b∗,则停止。否则,返回
σ
=
(
x
1
,
m
1
′
,
…
,
x
ℓ
,
m
ℓ
′
)
\sigma = (x_{1,m'_1},\dots,x_{\ell,m'_{\ell}})
σ=(x1,m1′,…,xℓ,mℓ′);
- 如果 A \mathcal{A} A 的查询正好落在位置 ( i ∗ , b ∗ ) (i^*,b^*) (i∗,b∗),而该位置的 x i ∗ , b ∗ x_{i^*,b^*} xi∗,b∗本应该是 y y y对应的 x x x,是未知的,终止实验。否则,正常返回签名。
- 当
A
\mathcal{A}
A 输出
(
m
,
σ
)
(m,\sigma)
(m,σ),
σ
=
(
x
1
,
…
,
x
ℓ
)
\sigma=(x_1,\dotsc,x_{\ell})
σ=(x1,…,xℓ),如果
A
\mathcal{A}
A 在
(
i
∗
,
b
∗
)
(i^*,b^*)
(i∗,b∗)输出了一个伪造的值,并且有
V
r
f
y
p
k
(
m
,
σ
)
=
1
\mathsf{Vrfy}_{pk}(m,\sigma)=1
Vrfypk(m,σ)=1 且
m
i
∗
=
b
∗
≠
m
i
∗
′
m_{i^*} =b^* \neq m'_{i^*}
mi∗=b∗=mi∗′,那么输出
x
i
∗
,
b
∗
x_{i^*,b^*}
xi∗,b∗;
- 通过验证并且在 y y y对应位置上输出签名,说明 A \mathcal{A} A 输出的签名满足 f ( x i , m i ) = y i , m i f(x_{i,m_i}) = y_{i,m_i} f(xi,mi)=yi,mi。
-
Pr
[
I
succeeds
]
≥
1
2
ℓ
Pr
[
A
succeeds
]
\Pr[\mathcal{I}\;\; \text{succeeds} ] \ge \frac{1}{2\ell}\Pr[\mathcal{A}\;\; \text{succeeds}]
Pr[Isucceeds]≥2ℓ1Pr[Asucceeds]
- 这是因为位置正好在特定位置满足条件的概率是 1 2 ℓ \frac{1}{2\ell} 2ℓ1.
-
I
\mathcal{I}
I算法构造
p
k
pk
pk:选择
i
∗
←
{
1
,
…
,
ℓ
}
i^* \gets \{1,\dotsc,\ell\}
i∗←{1,…,ℓ} 并且
b
∗
←
{
0
,
1
}
b^* \gets \{0,1\}
b∗←{0,1},令
y
i
∗
,
b
∗
:
=
y
y_{i^*,b^*} := y
yi∗,b∗:=y。对于
i
≠
i
∗
i \neq i^*
i=i∗
y
i
,
b
:
=
f
(
x
i
,
b
)
y_{i,b} := f(x_{i,b})
yi,b:=f(xi,b);
-
有状态签名方案
- 思路:为了对任意数量的消息签名,可以从旧状态中获得新的密钥并以此来实现和OTS一样的效果
- 定义:有状态签名方案(Stateful signature scheme)
- 密钥生成算法: ( p k , s k , s 0 ) ← G e n ( 1 n ) (pk,sk,s_0) \gets \mathsf{Gen}(1^n) (pk,sk,s0)←Gen(1n)。 s 0 s_0 s0 是初始状态。
- 签名算法: ( σ , s i ) ← S i g n s k , s i − 1 ( m ) (\sigma,s_i) \gets \mathsf{Sign}_{sk,s_{i-1}}(m) (σ,si)←Signsk,si−1(m)。
- 验证算法: b : = V r f y p k ( m , σ ) b:= \mathsf{Vrfy}_{pk}(m,\sigma) b:=Vrfypk(m,σ).
- 一个简单的有状态OTS签名方案:独立产生
(
p
k
i
,
s
k
i
)
(pk_i,sk_i)
(pki,ski),令
p
k
:
=
(
p
k
1
,
…
,
p
k
ℓ
)
pk := (pk_1,\dotsc,pk_{\ell})
pk:=(pk1,…,pkℓ) 并且
s
k
:
=
(
s
k
1
,
…
,
s
k
ℓ
)
sk := (sk_1,\dotsc,sk_{\ell})
sk:=(sk1,…,skℓ)。 从状态
1
1
1 开始,用
s
k
s
sk_s
sks 签第
s
s
s 个消息,用
p
k
s
pk_s
pks 来验证,并且更新状态到
s
+
1
s+1
s+1。
- 安全性:每个密钥只签了一个消息。
- 弱点:消息数量上届 ℓ \ell ℓ 必须事先确定。
-
链式签名
- 思路:按需随时产生密钥并且对密钥链签名,解决消息数量有上限的问题。
- 最初使用一个公钥 p k 1 pk_1 pk1,用 s k i sk_i ski 来对每个当前消息 m i m_i mi 和下一个公钥 p k i + 1 pk_{i+1} pki+1 签名 : σ i ← S i g n s k i ( m i ∥ p k i + 1 ) , \sigma_i \gets \mathsf{Sign}_{sk_i}(m_i\| pk_{i+1}), σi←Signski(mi∥pki+1), 输出 ⟨ p k i + 1 , σ i ⟩ \langle pk_{i+1},\sigma_i \rangle ⟨pki+1,σi⟩, 并且用 p k i pk_i pki 验证 σ i \sigma_i σi,签名 ( p k i + 1 , σ i , { m j , p k j + 1 , σ j } j = 1 i − 1 ) (pk_{i+1},\sigma_i,\{m_j,pk_{j+1},\sigma_j\}^{i-1}_{j=1}) (pki+1,σi,{mj,pkj+1,σj}j=1i−1)。
- 弱点:仍然有状态,包括之前签过的所有消息,效率低,需要揭示之前所有消息才能验证当前消息。
-
树式签名
- 思路:减少所需维护状态,构造一个密钥树,树上的一个分支是为每个消息生成一个密钥链并且对这个链签名。
- 根据按消息中的比特构造一个二叉树,根为 ε \varepsilon ε (空串),叶子为消息 m m m,并且内部节点为密钥对 ( p k w , s k w ) (pk_w,sk_w) (pkw,skw),其中 w w w 是 m m m 的前缀。
- 每个节点 p k w pk_w pkw 负责对其子节点公钥 p k w 0 ∥ p k w 1 pk_{w0}\| pk_{w1} pkw0∥pkw1 或消息 w w w 来签名。
-
无状态签名
- 思路:用确定的随机性来模拟树的状态。
- 使用PRF
F
F
F 和两个密钥
k
,
k
′
k,k'
k,k′ 来产生
p
k
w
,
s
k
w
pk_w,sk_w
pkw,skw:
- 计算 r w : = F k ( w ) r_w := F_k(w) rw:=Fk(w)。
- 计算 ( p k w , s k w ) : = G e n ( 1 n ; r w ) (pk_w,sk_w) := \mathsf{Gen}(1^n;r_w) (pkw,skw):=Gen(1n;rw), 用 r w r_w rw 作为随机硬币。
- k ′ k' k′ 用于产生 r w ′ r_w' rw′ ,后者在产生签名 σ w \sigma_w σw 时使用。
- 如果 OWF 存在,那么 ∃ \exists ∃ OTS (对于任意长度消息)。
- 定理:如果 OWF 存在,那么 ∃ \exists ∃ (无状态) 安全签名方案。
-
证书
- 从之前的方案中可以观察到,一种安全地分发公钥的方法是对该公钥做一个数字签名。
- 对一个公钥的数字签名被称为,数字证书(Certificate);专门签发数字证书的机构被称为,证书权威机构(Certificate Authority,CA),CA是一个可信的第三方,其公钥( p k C pk_C pkC)被所有相信CA的主体所持有。
- 一个数字证书 c e r t C → B = def S i g n s k C ( ‘Bob’s key is p k B ’ ) \mathsf{cert}_{C\to B} \overset{\text{def}}{=} \mathsf{Sign}_{sk_C}(\text{`Bob's key is } pk_B\text{'}) certC→B=defSignskC(‘Bob’s key is pkB’),表示 CA 用其私钥( s k C sk_C skC)给一个主体 Bob 签发的数字证书,其中消息内容包括:主体的身份(Bob)和该主体所持的公钥( p k B pk_B pkB)。其本质是绑定一个身份和一个公钥。
- Bob 将自己的公钥提交给 CA,然后收到证书,最后将自己的公钥和证书一起发送给通信的另一个方。
- 一个问题是 CA 的公钥是如何分发的?通常随应用程序一起分发,例如浏览器中内置了全世界约170个左右的CA的公钥。在DNSSEC中,递归服务器软件中内置了DNS根的公钥。
- 另一个问题:CA如何知道收到的公钥是否是Bob的?需要采用其它渠道,例如一个CA “Let’s Encrypt” 通过证明域名的所有权来识别证书申请者的身份。
-
公钥基础设施(PKI)
- 单一 CA: 被所有人信任。
- 优点:简单
- 缺点:单点失效
- 多重CA:被所有人信任。
- 优点:鲁棒
- 缺点:水桶定律
- 授权与证书链(Delegation,certificate chains):信任可以被传递。
- 优点:减轻根 CA 的负担
- 缺点:难以管理,水桶定律
- 信任网(Web of trust):没有信任的中心,例如,PGP。
- 优点:可靠,草根级
- 缺点:难以管理,难以对信任作出保证
- 单一 CA: 被所有人信任。
-
TLS 1.3 握手协议
- 目的:客户端与认证的服务器之间产生密钥
- 要求:客户端具有可信第三方的公钥,服务器具有由可信第三方发布的服务器公钥证书
- 协议主要步骤包括:
- 双方发送Hello消息,交换随机参数,各自DHKE公钥,同时也对所用的密码学套件和协议版本号进行协商;
- 分别根据交换信息根据DHKE生成共享秘密,进一步根据共享秘密和所有消息的哈希值派生出共享密钥
- 以下的消息都用上一步生成的对称密钥加密
- server端发送公钥证书,和用该公钥对应私钥来签名之前传递的消息(trans),以证明自己是证书的持有者;发送Finished结束消息,其中包含之前所有消息的HMAC;根据发送的所有消息和共享密钥生成应用密钥
- client验证证书和签名,并生成应用密钥
-
无效化证书
-
当私钥泄漏发生时,需要更换公私钥对,并将之前旧的公钥证书无效化。
-
过期法(Expiration):在证书中包含一个过期时间,待过期后自动作废。
c e r t C → B = def S i g n s k C ( ‘bob’s key is p k B ’ , date ) . \mathsf{cert}_{C \to B} \overset{\text{def}}{=} \mathsf{Sign}_{sk_C}(\text{`bob's key is}\; pk_B \text{'},\; \text{date}). certC→B=defSignskC(‘bob’s key ispkB’,date).
-
撤销/召回法(Revocation): 显式地撤销证书。
c e r t C → B = def S i g n s k C ( ‘bob’s key is p k B ’ , ### ) . \mathsf{cert}_{C \to B} \overset{\text{def}}{=} \mathsf{Sign}_{sk_C}(\text{`bob's key is}\; pk_B \text{'},\; \text{\#\#\#}). certC→B=defSignskC(‘bob’s key ispkB’,###).
其中的 ### 表示证书的序列号。
累积撤销:CA 产生证书撤销列表(Certificate revocation list,CRL)包含所有被撤销证书的序列号,并且带着当前日期一起签名。
-
-
独占所有权(Exclusive Ownership)
- 独占所有权:给定任意公钥的签名,没有敌手能够使得该签名可以被另一个不同的公钥验证。
- 重复签名公钥选择攻击:
- 一个签名由Bob的公钥验证有效,是否意味着Bob永其私钥产生了该签名?
- 不能。例如,Bob的用密钥对 ( e = 1 , d = 1 ) (e=1, d=1) (e=1,d=1) 和 N = σ − m N = \sigma - m N=σ−m。可以通过验证, σ e m o d N = σ m o d ( σ − m ) = m \sigma^e \mod N = \sigma \mod (\sigma - m) = m σemodN=σmod(σ−m)=m。
- 该攻击被用来在域名的所有权上欺骗Let‘s Encrypt系统。
- 防御:在验证之前检查公钥。
-
签名加密(Signcryption)
- 一群人相互直接通信,每个人生成两对密钥: ( e k , d k ) (ek, dk) (ek,dk)表示加密公钥和解密私钥; ( v k , s k ) (vk, sk) (vk,sk)表示验证公钥和签名私钥。大家知道彼此的两个公钥。当一个发送者 S S S向接收者 R R R发送一个消息 m m m时,如何在CCA攻击下同时保证通信的机密性(其他人不能知道消息 m m m)和完整性(接受者 R R R确信消息来自发送者 S S S)?
- 提示:下面的问题的关键在于“完整性”,即是否能能够伪装为其他人发送消息。
- “先加密后认证”:消息
<
S
,
c
←
E
n
c
e
k
R
(
m
)
,
S
i
g
n
s
k
S
(
c
)
>
\left< S, c \leftarrow \mathsf{Enc}_{ek_R}(m), \mathsf{Sign}_{sk_S}(c) \right>
⟨S,c←EncekR(m),SignskS(c)⟩ 是否安全?
- 注:消息中包含发送者身份是必要的,因为接收者需要用发送者的验证公钥来验证签名;消息中不包含接收者身份,因为接收者默认收到的消息都是发给自己的(直接通信,不存在中转)。
- 完整性有问题,发送者被伪造。因为敌手 A A A可以去掉签名部分,替换成自己的身份和签名, < A , c ← E n c e k R ( m ) , S i g n s k A ( c ) > \left< A, c \leftarrow \mathsf{Enc}_{ek_R}(m), \mathsf{Sign}_{sk_A}(c) \right> ⟨A,c←EncekR(m),SignskA(c)⟩ 。
- “先认证再加密”:先签名,
σ
←
S
i
g
n
s
k
S
(
m
)
\sigma \leftarrow \mathsf{Sign}_{sk_S}(m)
σ←SignskS(m),然后发送消息
<
S
,
E
n
c
e
k
R
(
m
∥
σ
)
>
\left< S, \mathsf{Enc}_{ek_R}(m\| \sigma) \right>
⟨S,EncekR(m∥σ)⟩ 是否安全?
- 完整性有问题,发送者被伪造。因为敌手 A A A可以解密后重新用另一个人 R ′ R' R′的加密公钥加密(不改变签名部分)后发送给 R ′ R' R′,使得 R ′ R' R′误认为是 S S S给他发的消息。
- 正确的方法是将身份应作为消息的一部分:签名中包含接收者身份
σ
←
S
i
g
n
s
k
S
(
m
∥
R
)
\sigma \leftarrow \mathsf{Sign}_{sk_S}(m \| R)
σ←SignskS(m∥R) ;加密消息中包含发送者身份
<
S
,
E
n
c
e
k
R
(
S
∥
m
∥
σ
)
>
\left< S, \mathsf{Enc}_{ek_R}(S\| m \| \sigma) \right>
⟨S,EncekR(S∥m∥σ)⟩。接收者解密后,提取发送者身份和接受者身份并验证。
- 这里的关键之一是签名将消息,发送者,接收者绑定在一起
- 当将身份和消息一起加密时,先加密后认证的方法也可以保证安全。
-
总结
- 数字签名提供了公开可验证的真实性和完整性
- 签名与只有某人知道的某物有关,这件事是可以公开验证的
- 签名用来将对一个公钥的信任转化为对其签名数据的信任