Elgamal
基本原理
密钥生成
- 选取一个足够大的素数 p(十进制位数不低于 160),以便于在Zp上求解离散对数问题是困难的。
- 选取Zp\*的生成元 g。(通常是g是p的原根)
- 选择一个私钥d,满足 1<d<p−1
- 计算y=gdmod p
- 公钥为(p,g,y),私钥为(d)。
签名
- 随机生成k,0<k<p,满足gcd(k,p−1)=1
- 计算r=gkmod p
- 计算s=(H(m)−dr)k−1mod p−1
- 返回(r,s)和H(m),若是明文m则存在伪造签名的可能
验签
- 验证gH(m)≡yrrsmod p
攻击方式
验签漏洞,未校验r和s的大小
已知gh≡yrrsmod p
构造h’,(r’,s’) St. gh’≡yr’r’s’mod p
∃h’=kh mod (p−1)
gm’≡gkm≡yr’r’s’≡ykrrksmod p
\left\{\begin{align}r’&=kr\ mod\ p-1 \\ r’&=r\ \ \ mod\ p\end{align}\right.
\Rightarrow \left\{\begin{align}r’&=crt(\[kr,r\],\[p-1,p\]) \\ s’&=ks\end{align}\right.
DSA数字签名
基本原理
密钥生成
- 选择一个哈希函数H(m),一般使用SHA1
- 确定长度N1和N2,使得N2不大于哈希长度
- 依据N1和N2作为比特长度生成p和q,满足gcd(p−1,q)=q
- 选择满足gk≡1 mod p的最小正整数k为q的g,即在模p的背景下,ord(g)=q。即g在模p的意义下,其指数次幂可以生成具有q个元素的子群。这里,我们可以通过计算g=hqp−1mod p来得到g,其中1<h<p−1.
- 选择私钥d,0<d<q,计算y≡gdmod p。
- 公钥为(p,q,g,y),私钥为(d)。
签名
- 随机生成k,0<k<q
- 计算r=(gkmod p)mod q
- 计算s=(H(m)+dr)k−1mod q
- 返回(r,s)和H(m)
验签
- 计算u1=H(m)s−1 mod q
- 计算u2=rs−1 mod q
- 验证r=(gu1yu2mod p)mod q
攻击方式
已知k
d=(ks−H(m))r−1mod q
复用k攻击
{s1=(H(m1)+dr)k−1mod qs2=(H(m2)+dr)k−1mod q
k=(H(m1)−H(m2))(s1−s2)−1mod q
线性k攻击
\left\{\begin{align}s_1&=(H(m_1)+d_1r)k^{-1}mod\ q \\ s_2&=(H(m_2)+d_2r)(ak+b)^{-1}mod\ q\end{align}\right.
\left\{\begin{align}ks_1r_2\equiv h_1r_2+xr_1r_2\ mod\ q \\ (ak+b)s_2r_1\equiv h_2r_1+xr_1r_2\ mod\ q\end{align}\right.
k=(h1r2−h2r1+bs2r1)(s1r2−as2r1)−1mod q
二次k攻击
k2=k12,可以看作a=k,b=0
k2s2r1−ks1r2+h1r2−h2r1=0 mod q
用Sage求解一元二次方程在有限域上的整数解
R.<k> = PolynomialRing(Zmod(q))
f = k^2*r1*s2 - k*r2*s1 - H2*r1 + H1*r2
roots=f.roots()
print(roots)
for i in roots:
k = i[0]
d = (k*s1-H1)*pow(r1,-1,q)%q
if y == pow(g,d,p):
print(k,d)
break
0 条评论