River5tone

RSA___Rivest&Shamir&Adleman

字数统计: 1.5k阅读时长: 7 min
2018/12/12 Share

一、RSA密码算法简介

RSARivest-Shamir-Adleman)是最早的公钥密码系统之一,广泛用于安全数据传输。公钥密码系统中,加密密钥是公共的(公钥),且它与保密的解密密钥(私钥)不同。在RSA中,这种不对称性算法的可靠性是基于两个大质数乘积的因子分解难题

1.算法流程
密钥生成
  1. 选择两个大素数p,q,计算$$N = pq$$(p,q为大素数)

    $$
    \varphi(n) = \varphi(p)*\varphi(q) = (p-1)(q-1)
    $$

  2. 选择随机数 $e$, $$ 1<e<\varphi(n) $$,$$ gcd(e,\varphi(n))=1 $$,

    计算私钥 $$ d = e^{-1} mod\varphi(n) $$

  3. 公开密钥(e,n),保密私钥(d,p,q)

加密

$$
c = m^emodn
$$

解密

$$
m = c^dmodn
$$

2.数字签名中的应用
签名

对消息字符串的散列值,使用 RSA 的私钥计算签名(实际上仍然是加密消息)后,得到一个签名字符串,与消息一并发送。

验证

接收方使用对应的公钥可以从签名字符串中解密出原来的散列值,同时对原始消息再计算一次散列值。二者相比较,假如两者相符的话,则认为发信人持有正确的私钥,发信人的身份得到认证,并且这个消息在传播路径上没有被篡改过。

3.密钥长度

用户应使用 1024 位密钥,证书认证机构应用 2048 位或以上。

4.OpenSSL

使用详见参考资料。



二、关于RSA的攻击


1.因数分解攻击

RSA的安全性依附于质因数分解的难度,若是密钥选用的整数不当,便可能遭受因数分解攻击。

针对因子分解的攻击:

  • Pollard’s Rho算法:可以快速找到合数的较小因子
  • Pollard’s P-1算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# -*- coding:UTF-8 -*-
#因子分解攻击
#Pollard's Rho
import math
import string

n = input()
e = input()
c = input()


def gcd(a,b):
trueif b == 0:
truetruereturn a
truereturn gcd(b,a%b)


def exgcd(a,b):
trueif b==0:
truetruereturn 1,0
truex,y = exgcd(b,a%b)
truetem = y
truey = x-(a//b)*y
truex = tem
truereturn x,y


def Rho(x,y):
trueglobal n
truewhile 1:
truetrueg = gcd(x-y,n)
truetrueif g>1 and g<n:
truetruetruereturn g
truetrueelif g == n:
truetruetruereturn 0
truetrueelif g == 1:
truetruetruex = (x*x+1)%n
truetruetruey = ((y*y+1)*(y*y+1)+1)%n


def getd(p):
trueglobal n
trueglobal e
trueq = n//p
truephi = (p-1)*(q-1)
truex,y = exgcd(e,phi)
truereturn x


for x in xrange(2,10):
truey = x*x+1
truep = Rho(x,y)
trueif p != 0 and p != 1:
truetrued = getd(p)
truetruem = pow(c,d,n)
truetrueprint(m)
truetruebreak

2.选择密文攻击

若签名密钥对与加密解密密钥对相同的话,可进行一种类似“欺骗”的攻击,将明文加入盲化因子,骗取对方签名,再去盲化因子得到明文。

窃听者已知李四发给张三$ c $($ c=m^e $)

选$ r<n $,计算$ t=r^{-1} mod n $,$ x=r^e mod n $,$ y=x*c mod n $

将$ y $发给张三,“欺骗”张三对$ y $进行签名,窃听者得到签名$ u=y^d mod n $

计算$ tu=r^{-1}y^d=r^{-1}(xc)^d=r^{-1}rm mod n $得到明文m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import math


def exgcd(a,b):
trueif b==0:
truetruereturn 1,0
truex,y = exgcd(b,a%b)
truetem = y
truey = x-(a//b)*y
truex = tem
truereturn x,y


n = input()
e = input()
c = input()

m1 = 2
c1 = pow(m1,e,n)

x,y = exgcd(m1,n)
re_m1 = x

v = (c1*c)%n
print(v)

u = input()
m = (re_m1*u)%n
print(m)

3.共用模数攻击

共用模数n时,攻击者可获得$ n,e_1,e_2,c_1,c_2 $

$$
c_1 = m^{e_1}modn
\c_2 = m^{e_2}modn
$$

若$e_1$和$e_2$互素,则有$ re_1+se_2=1 $

可以根据$ c_1^r*c_2^s=m^{re_1+se_2}=m mod n $

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- coding:UTF-8 -*-
import sys
sys.setrecursionlimit(1000000) #扩栈


def exgcd(a,b):
trueif b==0:
truetruereturn 1,0
truex,y = exgcd(b,a%b)
truetem = y
truey = (x-(a//b)*y)
truex = tem
truereturn x,y


n = input()
e1 = input()
c1 = input()
e2 = input()
c2 = input()

r,s = exgcd(e1,e2)

#!
if r<0:
truer = -r
truec1,y = exgcd(c1,n)
if s<0:
trues = -s
truec2,y = exgcd(c2,n)


m = (pow(c1,r,n)*pow(c2,s,n))%n
print(m)

4.CRT优化分解(加速RSA)失败时引起私钥泄露
CRT加速原理

$$
\begin{align}
&d=e^{-1}mod\varphi(n)
\Rightarrow (dp=e^{-1}mod(p-1),dq=e^{-1}mod(q-1))
\ &y=x^dmodn
\Rightarrow (y_1=x^{dp(q-1)(q-1)^{-1}mod(p-1)}mod p
,y_2=x^{dq(p-1)(p-1)^{-1}mod(q-1)}modq)
\ &y = y_2+q(q^{-1}(y_1-y_2) modp)
\end{align}
$$

通过上述 CRT,底数和指数均减小了,加快了运算速度。

私钥泄露

若$y_1$或$y_2$产生了计算错误,可能性较大是在$y_1$或$y_2$的计算过程时产生了错误。

  • 无错误时:

$$
\begin{align}
&x=y^emodn
\Rightarrow (x_1=y_1^emodp,x_2=y_2^emodq)
\ &x = (y_1^eqq^{-1}modp+y_2^epp^{-1}modq)modn
\ &x = (y_1^eq^{p-1}+y_2^ep^{q-1})mod n
\end{align}
$$

  • 假设$ y_1 $发生计算错误,错误算为$ y_1’ $,则$ x $误算为$ x’ $

    $$
    \begin{align}
    x’ &= (y_1’^eq^{p-1}+y_2^ep^{q-1})mod n
    \x’-x &= (y_1’^e-y_1^e)*q^{p-1}mod n
    \end{align}
    $$

    所以,

    大概率存在$ gcd(x’-x, n) = gcd(y^e-x, n) = q $

    解得q后可进行接下来的破解运算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import gmpy2

n = 317414783130165821045808930175617487601464670537823074592040709814439313429421170598096208692643181034555847239250461818568337890685803184993214355150334258064652250655643333567514373079127819952425740240056923848357657994723714554195062350207713120421222489778323142892993955679298208610869154670046475006253088141064370916548439054432244743695401792118444879262315002312654072545614448386852556641363183630761461501385451019411338842456735465115965319263560063646358653409938833605815022512370580090225483411694647809348209846840068278422177226702772182355075508529105926757724838388693883383910738155331571978924637416651098643111761325536420929467467295222943383203775975904926536083720347352981017431212906798517062595435424372927242747868846532427770029518638490921

e = 65537

m = 1066524364

c = 193482739944681472166649268398841256432266736840779533320141478366146561102433051287906778400856535734640533589535380018088047120252613168623083863627090014951883162534169365088522364459198619069204933607573820078075082411998324694346565612621424283800812109520139228816207125011379396420082030271744450911746811589257699610824438265850554262393906867550020386206426106295536511787488224220918456147396849783633623105573269317052260483910319720500504712711893111986143781088719391027185642831811927521318923707568350575988573880413630407329415277711875326921962451030666529992050768662684524216881840010936765724472307998320454246486649271134011152290057160437983027614696753184949072167115560166832457100113730862782304985106517460772420790481451071438951798306995834912

y = gmpy2.mpz(c)
x = gmpy2.mpz(m)
e = gmpy2.mpz(e)
n = gmpy2.mpz(n)

q = gmpy2.gcd(pow(y,e,n)-x,n)
p = n//q

print(p)
print(q)

phi = (p-1)*(q-1)

d = gmpy2.invert(e,phi)
print(d)

5.低加密指数广播攻击

广播攻击发生在加密使用的em相同,而n不同的时候。

当e比较小时例如e=3时,

$$
c_1 = m^3modn
\c_2 = m^3modn
\c_3 = m^3modn
$$

利用中国剩余定理CRT计算可得到$ m^3 $,开三次根在一定条件下可以得到明文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import gmpy2
import gmpy

n1 = 19851375730109702147410111547354144221875457321031223697134537152662954284778035659726777836419173602074243675379474758042251574628709204015344630121722181081357947554864577012170759352751954056863634879277235566401052896903737915168025406120485821600575222177565339908483871231963345316325883880725805183642711886174973831560524323612262245625356867125808729291910241533822929104554191436887669275590954686677553317406770308567916811827616983415494452891552691357470886986580784689791637773270366691010488804490695335088232109363335726209752067510335487027948414237789259493071147119114207873564472255092787796548757
e1 = 3
c1 = 13454882946725216336041450149747912801345150897738269747319625457896248720170984223193236484534898137077301146985964053694050587114190081392420937926436398915166732221806147601326052804974598044401237369173872313727529418915224956452544247250395436614772904692858338345883362615830546358880178712003244051534635046041882852867263201374871209754801875383118920093306257191680420637858437331213661376601491056259663126310104282784895433487635261665632335398264707493652353887185570468343007234872853922612324354135362251045303050159390094257102957492540509071506452893423235001402946205906541435403199551892986374804920


n2 = 26173521773502483247597089125243271820677225372183032349481812213016725381309207331835749003553831554633140540489226837866262707465143723936787003842437739219695454025969846598168174437311116014531279790307600380343936852182714366426205276301534919963285316772313717938106432099542920318855434061615067172765247575458191567464963759236522075416365378512744932616647264073550477949168527127402025096578055512157336517624334623370255903913904590248155257738134523374649246351120963720090091717538463753218892797487756700017617593544916093999491492264335912330825446605892101262194414610122257588430781728196281222326651
e2 = 3
c2 = 13505913121068470220847964312710175156127986501306214129578806436961037400323893789715303603187803738093907369047899145934457596188311642310861028144773439633531605220508808140662455716670082475842080321970571163395148402130729296994642849239816204269873047205730800760989269793676473215155256331437661051503440037546831165029304263381250709273274732332158416367294821131012710190159262730579799708286031962242459049360890723076878496179124292728671677882488465347042310943034512325729185236397374244668132954343101850740961483761474738710909332537524142175876638720302151108710719145864015333307963483395995537718237


n3 = 21202818797998627515352334625994038311482995714221672591450790765515673401535030894775203361099711195656344673329068886519004082528476627094716954416561909940135293365319683026068015518128387635258888254158981811317777785864346252540152216898844697734341077863453519579609431124462134201561065624730763893560814943258405090316816207636751619251737723450504065388791809103078820291564967984392756678881814377646778632427962036034448591000014370204337562273165150667491895831948436446074304718602008919196536063662377670980534229222981374594541340748663430129312248249332521398553163699869169510362600703426150991680327
e3 = 3
c3 = 2635549585896987063596747996023030662880935298112353023391070236788009696866126812856463364148603345293543937750291213077386941083306976983900924726863039062657867962813245750120467702651250543524273657372522053114010217848432895770161412721991002769186252112683680365847580401603924973909985759574698735663384486805551640031571297336457567716862973639891400022554522747237776054570299366418332408201620428338348053622395238810600517412562626967908191234817960510861906168470293686081083205722204699391858263306642439567802298290619076110468756807006508224515918448157214084863411103786533238277029555517164882404883

n1 = gmpy2.mpz(n1)
n2 = gmpy2.mpz(n2)
n3 = gmpy2.mpz(n3)
c1 = gmpy2.mpz(c1)
c2 = gmpy2.mpz(c2)
c3 = gmpy2.mpz(c3)

n = n1*n2*n3
w1 = n//n1
w2 = n//n2
w3 = n//n3
t1 = gmpy2.invert(w1,n1)
t2 = gmpy2.invert(w2,n2)
t3 = gmpy2.invert(w3,n3)

c = (c1*w1*t1+c2*w2*t2+c3*w3*t3)%n
c = int(c)
print(c)

m = gmpy.mpz(c).root(3)[0].digits()#开三次根gmpy库方法
print(m)


三、RSA相关CTF题目(待后续填坑继续挖坑



参考文献:

[1] RSA(cryptosystem) WIKI

[2] 段段PPT

[3] RSA-原理、特点(加解密及签名验签)及公钥和私钥的生成

[4] OpenSSL用法详解

[5] RSA-CRT leaks__因使用中国余数定理计算RSA所引起的私钥泄露

CATALOG
  1. 1. 一、RSA密码算法简介
    1. 1.1. 1.算法流程
      1. 1.1.1. 密钥生成
      2. 1.1.2. 加密
      3. 1.1.3. 解密
    2. 1.2. 2.数字签名中的应用
      1. 1.2.1. 签名
      2. 1.2.2. 验证
    3. 1.3. 3.密钥长度
    4. 1.4. 4.OpenSSL
  2. 2. 二、关于RSA的攻击
    1. 2.1. 1.因数分解攻击
    2. 2.2. 2.选择密文攻击
    3. 2.3. 3.共用模数攻击
    4. 2.4. 4.CRT优化分解(加速RSA)失败时引起私钥泄露
      1. 2.4.1. CRT加速原理
      2. 2.4.2. 私钥泄露
    5. 2.5. 5.低加密指数广播攻击
  3. 3. 三、RSA相关CTF题目(待后续填坑继续挖坑)
  4. 4. 参考文献: