Chapter 2 可证明安全(Provable Security)基础
要想证明安全性,首先需要对安全进行定义,才能证明某一个方法能够保证什么安全性,或者说明它为什么不安全。毕竟密码学并不能解决所有安全问题。
文章目录
一、安全定义(security definition)
1、对称密钥密码
定义2.1 对称密钥密码(symmetric-key encryption,SKE)通常由以下三个算法构成:
- K e y G e n KeyGen KeyGen:一个随机算法,生成一个密钥 k ∈ K k \in K k∈K( K K K称为密钥空间,下面类似)
- E n c Enc Enc:加密算法,输入明文 m ∈ M m \in M m∈M和密钥 k ∈ K k \in K k∈K,输出密文 c ∈ C c \in C c∈C
- D e c Dec Dec:解密算法,输入密文 c ∈ C c \in C c∈C和(同一个)密钥 k ∈ K k \in K k∈K,输出明文 m ∈ M m \in M m∈M
上述三个算法的集合记为 Σ \Sigma Σ,里面的元素可以如 Σ . K e y G e n \Sigma.KeyGen Σ.KeyGen表示。
2、正确性的定义
定义2.2 一个对称密钥密码算法是正确的,意味着对于所有的
k
∈
K
k \in K
k∈K和
m
∈
M
m \in M
m∈M,都满足:
P
r
[
Σ
.
D
e
c
(
k
,
Σ
.
E
n
c
(
k
,
m
)
)
=
m
]
=
1
Pr[\Sigma.Dec(k, \Sigma.Enc(k, m))=m]=1
Pr[Σ.Dec(k,Σ.Enc(k,m))=m]=1
这个定义比较容易理解,就是用同一密钥解密密文后,必须得到的是原来的明文,才能是正确的。
3、安全性的定义
(1)基本概念
在正式介绍安全性的形式化定义前,先介绍一些概念。我们将把密码算法和偷听者的攻击视为一些程序,因此需要先了解以下概念。
定义2.3 一个库(library) L L L是一些子程序(也可以理解为函数)和私有变量(比如密钥)的集合。库的接口是其中所有子程序的名字、输入输出参数。如果一个程序(program) A A A调用了 L L L中的一些子程序,那么 A ⋄ L A\diamond L A⋄L就是实际调用后的输出结果(可以理解为程序 A A A与函数库 L L L链接,然后执行 A A A)。
库可以理解为一些函数的源代码,对于偷听者而言是知道的;但是在执行过程中,那些私有变量的真实取值是不知道的——这是符合Kerckhoffs原则的。
定义2.4 库的等价性(Interchangeable):对于两个有相同接口的库
L
l
e
f
t
,
L
r
i
g
h
t
L_{left},L_{right}
Lleft,Lright,两者等价(
L
l
e
f
t
≡
L
r
i
g
h
t
L_{left}\equiv L_{right}
Lleft≡Lright)当且仅当对于所有输出结果为布尔值的程序
A
A
A,都有
P
r
[
A
⋄
L
l
e
f
t
⇒
t
r
u
e
]
=
P
r
[
A
⋄
L
r
i
g
h
t
⇒
t
r
u
e
]
Pr[A\diamond L_{left} \Rightarrow true]=Pr[A\diamond L_{right} \Rightarrow true]
Pr[A⋄Lleft⇒true]=Pr[A⋄Lright⇒true]
由定义可知,如果判断两个库相等,需要计算概率。不过在一些简单情况下,也可以根据库进行具体判断(相当于看库中的代码),比如输出结果可能与某些输入参数无关,或者有一些不可达的分支(如下所示)。
(2)安全性的两种定义
目前对于安全性有两种角度的理解。
第一种称为“real vs random”,也就是如果加密所得的真实密文的概率分布,看起来和随机(均匀)选取一个密文一样,那么偷听者将无法从密文中获取信息。下面是形式化定义:
定义2.5 一个密码算法
Σ
\Sigma
Σ有一次性的均匀分布的密文(one-time uniform ciphertexts),当且仅当
图中的$符号代表其中含有的随机性。
第二种安全性的定义称为“left vs right”,也就是对于任意的两个明文,他们所得的密文的概率分布是一样的,因此无法区分。下面是形式化定义:
定义2.6 一个密码算法
Σ
\Sigma
Σ有一次性安全性(one-time secrecy),当且仅当:
在第一章中提到的一次性密码本,就满足上述两种安全性的定义。
(3)两种安全性定义的关系
定理2.1 满足定义2.5则一定满足定义2.6,即 L o t s − r e a l Σ ≡ L o t s − r a n d Σ ⇒ L o t s − L Σ ≡ L o t s − R Σ L_{ots-real}^\Sigma \equiv L_{ots-rand}^\Sigma \Rightarrow L_{ots-L}^\Sigma \equiv L_{ots-R}^\Sigma Lots−realΣ≡Lots−randΣ⇒Lots−LΣ≡Lots−RΣ
证明:第1步将其拆成了库的调用,主要是因为已知部分的输入只有一个参数。然后第2步是使用了条件(real和rand等价)。第三步是因为rand算法的结果与输入参数无关,因此可以换参数。第4步再次使用条件,最后得证。
这里的等价变化其实也是用了hybrid方法,详见本章的第三节
定理2.2 满足定义2.6不一定满足定义2.5。
证明:只要给出一个反例即可。比如下面这个密码算法,它是在一次性密码本的基础上,密文末尾加了两个0。由于一次性密码本是满足定义2.6的,因此对于任意两个明文,末尾加0后,两者的密文的概率分布仍然相同,因此满足定义2.6。但是在当前的密文空间上,一个明文加密所得的密文必然以00结尾,不满足均匀分布,故不满足定义2.5。
这里并没有说哪一种安全性定义更优,而是应当看更关注定义中什么性质
二、如何证明不安全
无论是哪种安全性的定义,我们只需要找到一个程序 A A A,使得安全性定义中的两个库的执行结果(概率)不一样,就能证明该密码算法是不安全的。下面给出一个简单的例子。
对于如下密码算法:
按照安全性定义2.5,需要证明如下两个库等价。显然,根据按位与的性质,对于real部分,如果输入的是全0,那么输出的密文一定是全0,这显然与右边的随机算法的输出的概率分布不同。
因此,可以找到如下的一个程序,这个程序将证明 P r [ A ⋄ L o t s − r e a l Σ ⇒ t r u e ] = 1 , P r [ A ⋄ L o t s − r a n d Σ ⇒ t r u e ] = 1 2 λ Pr[A\diamond L_{ots-real}^\Sigma \Rightarrow true]=1,Pr[A\diamond L_{ots-rand}^\Sigma \Rightarrow true]=\frac{1}{2^\lambda} Pr[A⋄Lots−realΣ⇒true]=1,Pr[A⋄Lots−randΣ⇒true]=2λ1,因此两个库不等价。
按照安全性定义2.6,需要证明如下两个库等价。
同样的思路我们可以找到如下的程序,证明两个库不等价。
三、使用Hybrid方法证明安全性
原文的词为Hybrid Technique,在此称为Hybrid方法。
根据安全性的定义,证明需要计算概率,如果密码算法十分复杂,那么可能难以计算。因此Hybrid方法是希望通过一些等价转换(中间的库就称为hybrids),将待证明安全的密码算法转化为已证明安全的密码算法,从而简化安全性的证明。在给出具体示例之前,先介绍一些引理。
第一个引理是 ( A ⋄ L 1 ) ⋄ L 2 (A\diamond L_1) \diamond L_2 (A⋄L1)⋄L2与 A ⋄ ( L 1 ⋄ L 2 ) A\diamond (L_1 \diamond L_2) A⋄(L1⋄L2)的结果相同。前者可以理解为,程序 A A A将一些 L 1 L_1 L1的函数内联(就是把调用的子程序直接展开),生成一个只调用 L 2 L_2 L2的程序。后者可以理解为是链接了一个复合库(compound library),即库 L 1 L_1 L1可以调用库 L 2 L_2 L2。
第二个引理则是等价库的性质:如果 L l e f t ≡ L r i g h t L_{left}\equiv L_{right} Lleft≡Lright,则任意的库 L ∗ L^* L∗,都有 L ∗ ⋄ L l e f t ≡ L ∗ ⋄ L r i g h t L^*\diamond L_{left} \equiv L^*\diamond L_{right} L∗⋄Lleft≡L∗⋄Lright 。证明如下:
这个引理将方便后续证明中,用已知的安全库的等价,对式子进行变换。
下面,给出一个简单的使用Hybrid方法证明安全性的例子:证明如下密码算法的安全性(定义2.5)。该密码算法是在一次性密码本(OTP)的基础上,多进行了一次加密(两次异或)。
证明:这里的思路是希望转化为已证明过安全性的一次性密码本(库的下标是otp,有
L
o
t
p
−
r
e
a
l
≡
L
o
t
p
−
r
a
n
d
L_{otp-real}\equiv L_{otp-rand}
Lotp−real≡Lotp−rand)。因此第一步是转化为一次性密码本。第二步则利用了一次性密码本的安全性(等价),根据第二个引理进行替换。第三步是将库进行内联。最后简化无用代码。
值得注意的是,在使用Hybrid方法的时候,一定要注意每一步的等价性,否则将出错。