本篇博文将介绍变色龙哈希函数。
在介绍变色龙哈希函数之前,我们先简单回顾一下经典的哈希函数,这样就能对比它们之间的差别。
一、哈希函数
哈希函数
H
a
s
h
(
)
Hash( )
Hash()是密码学中经常用到的一个函数(记住它并不是加密技术,独立于非对称加密和对称加密之外的函数),任意大小的输入消息
m
m
m经过哈希函数
H
(
)
H( )
H()映射成一个固定长度的输出值
h
h
h,通常称
h
h
h为哈希值或哈希摘要,即
h
=
H
(
m
)
h=H(m)
h=H(m)具有三个特别重要的性质:
- 1)单向性:从输入到输出的计算过程较为容易,而由输出值推出输入值是不可能的(计算上几乎不可能实现);
- 2)抗碰撞性:一般分为弱抗碰撞性和强抗碰撞性(一般很容易搞混,注意区分)
- 弱抗碰撞性:任意给定消息 m m m,寻找 m ′ ( m ′ ≠ m ) m'(m'\neq m) m′(m′=m),使得 H ( m ′ ) = H ( m ) H(m')=H(m) H(m′)=H(m)在计算上是不可能的;
- 强抗碰撞性:找到任意两个相同哈希值 H ( m ) = H ( m ′ ) H(m)=H(m') H(m)=H(m′)的不同消息对 ( m , m ′ ) (m, m') (m,m′)在计算上是不可能的。
- 3)高灵敏性:输入若发生非常非常微小的变化(甚至加个标点符号或空格),则输出值会发生巨大的变化(至少一半长的比特位变化)。
一句话概括哈希函数:将任意长度、类型或大小的字符串输入到哈希函数中,输出固定长度的字符串。
二、变色龙哈希函数
变色龙哈希函数(Chameleon Hash),听名字感觉就很怪,一个哈希函数怎么跟小动物相关呢,一开始我看到这个中文译名也是一样感觉。可以这样理解,变色龙是一种会随着周围环境变化而改变自身颜色的小动物,而哈希函数又是一种只知道输出而无法知道输入的函数,两者结合起来,是否可以理解为变色龙哈希函数的某种情况下知道输出可以推出输入?
定义:任何人可以通过给定的公钥 p k pk pk进行变色龙哈希后,拥有 s k sk sk的用户可以广义地找到哈希碰撞,即使得 C h _ H a s h ( m ′ ) = C h _ H a s h ( m ) Ch\_Hash(m')=Ch\_Hash(m) Ch_Hash(m′)=Ch_Hash(m)。
变色龙哈希函数具有4个主要的算法:
- 1)密钥生成算法
C
h
_
G
e
n
(
1
λ
)
=
(
p
k
,
s
k
)
Ch\_Gen(1^\lambda)=(pk, sk)
Ch_Gen(1λ)=(pk,sk):给定一个安全常数
λ
\lambda
λ,输出变色龙哈希的公钥
p
k
pk
pk和私钥
s
k
sk
sk(陷门);
- 2)哈希生成算法
C
h
_
H
a
s
h
(
p
k
,
m
,
r
)
=
(
h
,
p
)
Ch\_Hash(pk, m,r)=(h, p)
Ch_Hash(pk,m,r)=(h,p):输入公钥
p
k
pk
pk、随机数
r
r
r和任意消息
m
m
m,生成哈希值
h
h
h和随机数
p
p
p;
- 3)哈希验证算法
C
h
_
V
e
r
(
p
k
,
m
,
(
h
,
p
)
)
Ch\_Ver(pk, m, (h, p))
Ch_Ver(pk,m,(h,p)):输入公钥
p
k
pk
pk、任意消息
m
m
m和哈希值
h
h
h、随机数
p
p
p,若
(
h
,
p
)
(h, p)
(h,p)是正确的哈希值,则输出1,否则输出0;
- 4)哈希碰撞算法
C
h
_
C
l
d
(
s
k
,
m
,
m
′
,
(
h
,
p
)
)
Ch\_Cld(sk, m, m', (h, p))
Ch_Cld(sk,m,m′,(h,p)):输入私钥
s
k
sk
sk(陷门)、消息
m
m
m、新消息
m
′
m'
m′和哈希值
h
h
h、随机数
p
p
p,输出新随机数
r
′
r'
r′,使得
C
h
_
V
e
r
(
p
k
,
m
,
(
h
,
p
)
,
r
)
=
C
h
_
V
e
r
(
p
k
,
m
′
,
(
h
,
p
)
,
r
′
)
=
1
Ch\_Ver(pk, m, (h, p), r)=Ch\_Ver(pk, m',(h, p), r')=1
Ch_Ver(pk,m,(h,p),r)=Ch_Ver(pk,m′,(h,p),r′)=1。
三、变色龙哈希的安全需求
- 1)抗碰撞性:在没有陷门 s k sk sk的情况下,输入消息 m 1 m_1 m1、随机数 r 1 r_1 r1和消息 m 2 m_2 m2,求满足 H a s h ( m 1 , r 1 ) = H a s h ( m 2 , r 2 ) Hash(m_1,r_1)=Hash(m_2,r_2) Hash(m1,r1)=Hash(m2,r2)的整数 r 2 r_2 r2是几乎不可能的。
- 2)陷门碰撞:在输入陷门 s k sk sk后,对于任意的 m 1 、 r 1 m_1、r_1 m1、r1,给定消息 m 2 m_2 m2,可以计算出 r 2 r_2 r2,满足 H a s h ( m 1 , r 1 ) = H a s h ( m 2 , r 2 ) Hash(m_1,r_1)=Hash(m_2,r_2) Hash(m1,r1)=Hash(m2,r2)。
- 3)语义安全:对于任意消息 m 1 , m 2 m_1, m_2 m1,m2,他们的 H a s h ( m 1 , r 1 ) Hash(m_1,r_1) Hash(m1,r1)和 H a s h ( m 2 , r 2 ) Hash(m_2,r_2) Hash(m2,r2)的概率分布在计算上是不可区分的。
四、基于离散对数的变色龙哈希函数的构造(举例)
假设 p 、 q p、q p、q为两个素数且 q q q为足够大的素数,其中 p 、 q p、q p、q满足 p = k q + 1 p=kq+1 p=kq+1, Z p ∗ Z^*_p Zp∗是一个阶为 p − 1 p-1 p−1的群, g g g是模 p p p的一个生成元。设陷门 s k sk sk为 x ∈ Z p ∗ x\in Z^*_p x∈Zp∗,则公钥 p k pk pk表示为 y = g x m o d p y=g^x mod\ p y=gxmod p,给定一个消息 m 1 ∈ Z p ∗ m_1 \in Z^*_p m1∈Zp∗和一个随机值 r 1 ∈ Z p ∗ r_1\in Z^*_p r1∈Zp∗,则消息 m 1 m_1 m1的CH值为 H a s h ( m 1 , r 1 ) = g m 1 y r 1 m o d p Hash(m_1,r_1)=g^{m_1} y^{r_1} mod\ p Hash(m1,r1)=gm1yr1mod p。
求任意给定 m 1 、 m 2 、 r 1 m_1、m_2、r_1 m1、m2、r1,能够找到 r 2 ∈ Z p ∗ r_2\in Z^*_p r2∈Zp∗,使得 H a s h ( m 1 , r 1 ) = H a s h ( m 2 , r 2 ) ? Hash(m_1,r_1)=Hash(m_2,r_2)? Hash(m1,r1)=Hash(m2,r2)?
解:
由于 H a s h ( m 1 , r 1 ) = g m 1 y r 1 m o d p = g m 1 + x r 1 m o d p Hash(m_1,r_1)=g^{m_1} y^{r_1} mod\ p = g^{m_1+xr_1} mod\ p Hash(m1,r1)=gm1yr1mod p=gm1+xr1mod p H a s h ( m 2 , r 2 ) = g m 2 y r 2 m o d p = g m 2 + x r 2 m o d p Hash(m_2,r_2)=g^{m_2} y^{r_2} mod\ p = g^{m_2+xr_2} mod\ p Hash(m2,r2)=gm2yr2mod p=gm2+xr2mod p
所以有
r
2
=
m
1
−
m
2
x
+
r
1
m
o
d
p
r_2=\frac{m_1-m_2}x+r_1\ mod\ p
r2=xm1−m2+r1 mod p
相应的代码实现,可以参考大佬写的java实现,见评论区!