关于RSA的几种攻击手段
1、公钥密码的简介
公钥密码包含两个密钥,加密密钥和解密密钥,其加密密钥是可以公开的,解密密钥是不能公开的。公钥密码自1976年提出这个思想后就不断发展,其一般是基于数学上的一些困难问题所建造的,如rsa基于大整数分解的困难问题建立的,椭圆曲线是基于椭圆曲线上的离散对数困难问题建立的,elgamal上的DH密钥交换是基于有限域的离散对数困难问题建立的,格密码是基于格中困难问题的难解程度建立的等等。但是随着科技的发展,在一定条件下,有些困难问题变得不在困难,如rsa密码体系参数的选取,选取的bit长度随着计算机的发展变得越来越长,这提高了存储空间和计算时间,所以研究新型的公钥体系变得越来越火热。下面将会介绍RSA的基本原理和由于参数选取不当造成的攻击手段。
2、RSA介绍
2.1、基本原理
我们选取两个大素数p和q,令n=pq,由欧拉函数的知识我们知道
ψ
(
n
)
=
(
q
−
1
)
∗
(
p
−
1
)
\psi(n) = (q-1)*(p-1)
ψ(n)=(q−1)∗(p−1) ,然后随机选取一个数e,保证gcd(e,
ψ
(
n
)
\psi(n)
ψ(n))=1,并且我们把e称作公钥。然后我们选取d,令ed=1mod
ψ
(
n
)
\psi(n)
ψ(n),即ed=k*
ψ
(
n
)
\psi(n)
ψ(n)+1,并把d称作私钥。
下面是加解密过程和原理:
2.2、攻击手段
在这里,我主要讲的攻击手段是由于参数选取不当所造成的攻击,太高级的攻击手段俺也不会(猛男落泪)。
2.2.1、直接分解n
如果当n不是特别大的话可以通过分解的方法算出p和q,继而算出私钥d。像1024bit以下的一般通过分解就可以把d求出来了,主要的方法有网站分解、利用yafu这个工具分解,另外就是基于费马分解法或者pollard p-1分解法进行分解。
①、网站分解
②、费马分解法
def fermat(n, verbose=True):
a = isqrt(n) # int(ceil(n**0.5))
b2 = a*a - n
b = isqrt(n) # int(b2**0.5)
count = 0
while b*b != b2 and count<1000000:
a = a + 1
b2 = a*a - n
b = isqrt(b2) # int(b2**0.5)
count += 1
p=a+b
q=a-b
#print(p)
#print(q)
return p, q
③、pollard p-1分解法
def pollard(n):
m = 2
ans=[]
max = n
for i in range(max):
if(i>0):
m = pow(m,i,n)
#print(i)
if (gcd(n,m-1) != 1):
return gcd(n,m-1)
2.2.2、低加密指数广播攻击
from Crypto.Util.number import inverse
import gmpy2
def gcd(a,b):
while a != 0:
a, b = b % a, a
return (b)
def sumed(a):
num = 1
for i in range(len(a)):
num *= a[i]
return (num)
def ive(Mi,mi):
return (inverse(Mi,mi))
def chinese_remain(n,c,e):
k = len(n)
med = n
isok = 1
for i in range(k-1):
for j in range(i+1,k):
if gcd(med[i],med[j])!=1:
isok = 0
break
if isok == 0:
break
if isok == 0:
print("m中存在两两不互素,不能直接利用中国剩余定理")
else:
a = c
M = []
invM = []
xk = []
num = sumed(med)
for i in range(k):
M.append( num//med[i] )
for i in range(k):
invM.append( int(ive(M[i],med[i])) )
for i in range(k):
xk.append( M[i]*invM[i]*a[i]%num )
xxx=sum(xk)%num
result=int(gmpy2.iroot(xxx,e)[0])
result=hex(result)[2:]
print(result)
return result
2.2.3、共模攻击
def common_mode(a):
n1=int(n[a[0]],16)
n2=int(n[a[1]],16)
e1=int(e[a[0]],16)
e2=int(e[a[1]],16)
c1=int(c[a[0]],16)
c2=int(c[a[1]],16)
s=egcd(e1,e2)
#print(n1,n2)
s1=s[0]
s2=s[1]
if s1 < 0:
s1 = - s1
c1 = inverse(c1, n1)
elif s2 < 0:
s2 = - s2
c2 = inverse(c2, n1)
m = pow(c1, s1, n1) * pow(c2, s2, n1) % n1
2.2.4、因数碰撞法
2.2.5、LLL算法的应用
LLL算法又叫做格基约简,是第一个具有实用价值的求格中短向量的多项式时间算法,在后面疯狂应用到密码设计与分析中,成为密码学非常有力的工具。其可以在已知p、q部分bit,并且p的未知部分的上界X和q的未知部分的上界Y满足X*Y ≤ \leq ≤ n \sqrt{n} n的情况下把n分解出来。并且这种方法在之后广泛应用于RSA体制的小指数攻击和部分私钥泄露攻击等领域,具体可见 LLL算法在RSA安全性分析中的应用。
3、总结
太不容易了,第一篇博客终于写完拉,写的不太好,有错误的地方请各位大佬即时指出。