本文读完需要20分钟
小指数明文爆破 (small e & c)
如果B使用的e很小,如e=3,且A传给B的明文也很小,如几个字节
那么,c = m^ e mod n 如果n很大 则可能 c = m^ e 即 c=m^ 3 即对c开三次根号
就可以得到m
如果m的三次方大于n但是没有超过太多
即 k*n <m^3 < (k+1)*n
且k是可以爆破的大小
k*n - c = m^3
例题1、
n=47966708183289639962501363163761864399454241691014467172805658518368423135168025285144721028476297179341434450931955275325060173656301959484440112740411109153032840150659
e=3
c=10968126341413081941567552025256642365567988931403833266852196599058668508079150528128483441934584299102782386592369069626088211004467782012298322278772376088171342152839
from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime, isPrime
import primefac
def modinv(a, n):
return primefac.modinv(a, n) % n
n = 47966708183289639962501363163761864399454241691014467172805658518368423135168025285144721028476297179341434450931955275325060173656301959484440112740411109153032840150659
e = 3
c = 10968126341413081941567552025256642365567988931403833266852196599058668508079150528128483441934584299102782386592369069626088211004467782012298322278772376088171342152839
import gmpy2
i = 0
while 1:
if (gmpy2.iroot(c + i * n, 3)[1] == 1):
print long_to_bytes(gmpy2.iroot(c + i * n, 3)[0])
break
i = i + 1
import gmpy2
gmpy2.mpz(n)#初始化一个大整数
gmpy2.mpfr(x)# 初始化一个高精度浮点数x
d = gmpy2.invert(e,n) # 求逆元,de = 1 mod n
C = gmpy2.powmod(M,e,n)# 幂取模,结果是 C = (M^e) mod n
gmpy2.is_prime(n) #素性检测
gmpy2.gcd(a,b) #欧几里得算法,最大公约数
gmpy2.gcdext(a,b) #扩展欧几里得算法
gmpy2.iroot(x,n) #x开n次根
选择密文攻击 (can’t decrypt c)
如果可以对任意密文解密
但不能对c解密
则使用选择密文攻击
首先求出c在n上的逆元 c^-1
再求 c^-1 的明文m ’ 为明文的逆元
再求逆
如果存在交互可以对任意密文进行解密,并获取1bit的话,则可以实现RSA parity oracle攻击
LLL-attack ( A reveal m )
如果B使用的e仍然是3,同时A在密文m前加了段说明,即密文的一部分已泄露
或者B泄露p或q的部分
可以通过Coppersmith method求得明文
例题2、
n=6605504825889906202615748618066615187648800018528841933516316527012434141085944518043517968365397208826746013914157780887914632131531725863903538584417200527430582588764927544641557369303652648618292067488950921453386626677080964591489000067415450844331150724748818976858613279276478837816955089131430026237158610099210296694041096318330028075396562522499372070896421812111982381954403594724817813599972527870269930328689605408419124792951097063104670279395547265345199330843872092262422909324703892472836919443820718316384657112213693649570846294917435669334446894791207245948586388312000876428472397897528075326181
e=3
base=0x9876543210fedcba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
m=base+x
c=509143472960679964712061323134017269675726146763840337342493411055818623664115844443674190631269444040761374004286322788918255893217259171816916764385142572139730607623044481570957838700886892396989322684261802615250176830520657672566986118693899055342488599895558649859959818014882032199503639959456476815874298279286366688505291464700166422158955162203921387290954912301297909167283802751188777341587497155942072022517346786613010384892896362040794853435381349
目前,GitHub上提供了进行LLLattack的sage代码 参考Git 脚本
使用sage-online sagemath
选择CoCalc 注册账号 sign in ,然后 create new project
import time
debug = True
# display matrix picture with 0 and X
def matrix_overview(BB, bound):
for ii in range(BB.dimensions()[0]):
a = ('%02d ' % ii)
for jj in range(BB.dimensions()[1]):
a += '0' if BB[ii,jj] == 0 else 'X'
a += ' '
if BB[ii, ii] >= bound:
a += '~'
print a
def coppersmith_howgrave_univariate(pol, modulus, beta, mm, tt, XX):
"""
Coppersmith revisited by Howgrave-Graham
finds a solution if:
* b|modulus, b >= modulus^beta , 0 < beta <= 1
* |x| < XX
"""
#
# init
#
dd = pol.degree()
nn = dd * mm + tt
#
# checks
#
if not 0 < beta <= 1:
raise ValueError("beta should belongs in (0, 1]")
if not pol.is_monic():
raise ArithmeticError("Polynomial must be monic.")
#
# calculate bounds and display them
#
"""
* we want to find g(x) such that ||g(xX)|| <= b^m / sqrt(n)
* we know LLL will give us a short vector v such that:
||v|| <= 2^((n - 1)/4) * det(L)^(1/n)
* we will use that vector as a coefficient vector for our g(x)
* so we want to satisfy:
2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n)
so we can obtain ||v|| < N^(beta*m) / sqrt(n) <= b^m / sqrt(n)
(it's important to use N because we might not know b)
"""
if debug:
# t optimized?
print "\n# Optimized t?\n"
print "we want X^(n-1) < N^(beta*m) so that each vector is helpful"
cond1 = RR(XX^(nn-1))
print "* X^(n-1) = ", cond1
cond2 = pow(modulus, beta*mm)
print "* N^(beta*m) = ", cond2
print "* X^(n-1) < N^(beta*m) \n-> GOOD" if cond1 < cond2 else "* X^(n-1) >= N^(beta*m) \n-> NOT GOOD"
# bound for X
print "\n# X bound respected?\n"
print "we want X <= N^