赞
踩
为了方便理解,先对RSA密钥体制做个简略的介绍。
- 选择两个大的参数,计算出模数 N = p * q
- 计算欧拉函数 φ = (p-1) * (q-1),然后选择一个e(1<e<φ),并且e和φ互质(互质:公约数只有1的两个整数)
- 取e的模反数d,计算方法为:e * d ≡ 1 (mod φ) (模反元素:如果两个正整数e和n互质,那么一定可以找到整数d,使得 e * d - 1 被n整除,或者说e * d被n除的余数是1。这时,d就叫做e的“模反元素”。欧拉定理可以用来证明模反元素必然存在。两个整数a,b,它们除以整数M所得的余数相等:a ≡ b(mod m),比如说5除3余数为2,11除3余数也为2,于是可写成11 ≡ 5(mod 3)。)
- 对明文m进行加密:c = pow(m, e, N),可以得到密文c。
- 对密文c进行解密:m = pow(c, d, N),可以得到明文m。
整理:
N
的的两个因子。模数
pow(x, y)1 % z
, 先计算x的y次方,如果存在另一个参数z
,需要再对结果进行取模。对于RSA加密算法,公钥(N, e)
为公钥,可以任意公开,破解RSA最直接(亦或是暴力)的方法就是分解整数N
,然后计算欧拉函数φ(n)=(p-1) * (q-1)
,再通过d * e ≡ 1 mod φ(N)
,即可计算出 d
,然后就可以使用私钥(N, d)
通过m = pow(c,d,N)
解密明文。
1.定期更换密钥
2.不同的用户不可以使用相同的模数N
3.p与q的差值要大,最好是差几个比特
4.p-1与q-1都应该有大的素因子,一般建议选择的两个大素数p、q使得p=2p+1和q=2q+1也是素数
5.e的选择不要太小
6.d的选择也是不可以太小,最好满足d>=n的4分之1
直接分解模数N
是最直接的攻击方法,也是最困难的方法。具体的解析同上RSA安全性分析
。
如果n
小于256bit,可以使用本地工具进行暴力分解,例如windwods平台的RSATool
,可以在数分钟之内完成256bit的n
的分解。
如果n
大于768bit,可以尝试利用在线网站http://factordb.com, 这一类在线网站的原理是储存了部分n
分解成功的的值。
题目链接:http://ctf5.shiyanbar.com/crypto/RSAROLL.txt
{920139713,19} 704796792 752211152 274704164 18414022 368270835 483295235 263072905 459788476 483295235 459788476 663551792 475206804 459788476 428313374 475206804 459788476 425392137 704796792 458265677 341524652 483295235 534149509 425392137 428313374 425392137 341524652 458265677 263072905 483295235 828509797 341524652 425392137 475206804 428313374 483295235 475206804 459788476 306220148
分解N
可以通过在线网站http://www.factordb.com/index.php
分解920139713
可以得到p
和q
的值为18443
和49891
,现在已知p
、q
、e
以及c
,可以通过前三个参数求出d
安装gmpy2
可以参考https://blog.csdn.net/wanzt123/article/details/71036184
import gmpy2
p = gmpy2.mpz(18443)#初始化大整数
q = gmpy2.mpz(49891)
e = gmpy2.mpz(19)
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)#invert(x,m)返回y使得x * y == 1 modulo m,如果不存在y,则返回0
print("p=%s,q=%s,e=%s"%(p,q,e))
print("d is:\n%s"%d)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
p=18443,q=49891,e=19
d is:
96849619
到目前为止,已经求出p,q,e,d,n,c,然后可以求出相应的明文M,
#求明文 import gmpy2 n = 920139713 d = 96849619 c = """ 704796792 752211152 274704164 18414022 368270835 483295235 263072905 459788476 483295235 459788476 663551792 475206804 459788476 428313374 475206804 459788476 425392137 704796792 458265677 341524652 483295235 534149509 425392137 428313374 425392137 341524652 458265677 263072905 483295235 828509797 341524652 425392137 475206804 428313374 483295235 475206804 459788476 306220148 """ result = "" c_list = c.split() #print(c_list) for i in c_list: result += chr(pow(int(i),d,n)) print(result)
- 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
适用于:使用相同的模数 N 、不同的私钥,加密同一明文消息
假如采用两个或者两个以上的公钥(N,e)来加密同一条信息,可以得到下面的结论:
c1 = pow(m, e1, N)
c2 = pow(m, e2, N)
分别拿对应的私钥来加密,可以得到相同的明文m
m = pow(c1, d1, N)
m = pow(c2, d2, N)
假设攻击者已知n,e1,e2,c1,c2,即可可以得到明文m,因为e1和e2互质,所以使用欧几里得算法
(用于计算两个整数a,b的最大公约数)可以找到能够满足以下条件的x
,y
:
pow(x,e1)+pow(y,e2)=1
假设x为负数,需再使用欧几里得算法来计算
pow(c1,-1)
则可以得到
pow(pow(c1,-1),-x) * pow(c2,y) = p mod(n)
如果p<n,则p可以被计算出来。
地址:https://www.ichunqiu.com/battalion?q=2451
# coding=utf-8 import gmpy2 def ByteToHex(bins): return ''.join(["%02X" % x for x in bins]).strip() def n2s(num): t = hex(num)[2:] if len(t) % 2 == 1: t = '0' + t return ''.join([chr(int(b, 16)) for b in [t[i:i + 2] for i in range(0, len(t), 2)]]) n = 0x00b0bee5e3e9e5a7e8d00b493355c618fc8c7d7d03b82e409951c182f398dee3104580e7ba70d383ae5311475656e8a964d380cb157f48c951adfa65db0b122ca40e42fa709189b719a4f0d746e2f6069baf11cebd650f14b93c977352fd13b1eea6d6e1da775502abff89d3a8b3615fd0db49b88a976bc20568489284e181f6f11e270891c8ef80017bad238e363039a458470f1749101bc29949d3a4f4038d463938851579c7525a69984f15b5667f34209b70eb261136947fa123e549dfff00601883afd936fe411e006e4e93d1a00b0fea541bbfc8c5186cb6220503a94b2413110d640c77ea54ba3220fc8f4cc6ce77151e29b3e06578c478bd1bebe04589ef9a197f6f806db8b3ecd826cad24f5324ccdec6e8fead2c2150068602c8dcdc59402ccac9424b790048ccdd9327068095efa010b7f196c74ba8c37b128f9e1411751633f78b7b9e56f71f77a1b4daad3fc54b5e7ef935d9a72fb176759765522b4bbc02e314d5c06b64d5054b7b096c601236e6ccf45b5e611c805d335dbab0c35d226cc208d8ce4736ba39a0354426fae006c7fe52d5267dcfb9c3884f51fddfdf4a9794bcfe0e1557113749e6c8ef421dba263aff68739ce00ed80fd0022ef92d3488f76deb62bdef7bea6026f22a1d25aa2a92d124414a8021fe0c174b9803e6bb5fad75e186a946a17280770f1243f4387446ccceb2222a965cc30b3929 e1 = 17 e2 = 65537 # gmpy2.gcdext(e1,e2)的运行结果为元组(mpz(1), mpz(30841), mpz(-8)),所以元组的第0个值不能取,第1个值才是s1,第2个值由于是负数,所以要取反,变为正数 # gcdext(a,b)返回一个3元素元组(g,s,t) # g == gcd(a,b)最大公约数和g == a * s + b * t s = gmpy2.gcdext(e1, e2) s1 = s[1] s2 = -s[2] file1 = open("veryhardRSA/flag.enc1", 'rb').read() # 这里的路径要自己修改 c1 = int(ByteToHex(file1), 16) file2 = open("veryhardRSA/flag.enc2", 'rb').read() # 这里的路径要自己修改 c2 = int(ByteToHex(file2), 16) # 由于根据前面的运算,s1是正数,s2是负数,后面需要运算c2的s2次幂。因为在数论模运算中,要求一个数的负数次幂,与常规方法并不一样,比如此处要求c2的s2次幂,就要先计算c2的模反元素c2r,然后求c2r的-s2次幂。 c2 = gmpy2.invert(c2, n) m = (pow(c1, s1, n) * pow(c2, s2, n)) % n print(n2s(m))
如果RSA系统的公钥e选取较小的值,可以使得加密和验证签名的速度有所提高,但是如果e的选取太小,就容易受到攻击。
有三个分别使用不同的模数n1,n2,n3,但是都选取e=3,加密同一个明文可以得到:
c1 = pow(m,3,n1)
c2 = pow(m,3,n2)
c3 = pow(m,3,n3)
一般情况下,n1,n2,n3互素,否则会比较容易求出公因子,从而安全性大幅度的减低。
在此种攻击模型中,攻击者需要掌握的内容包括:加密算法、截获的部分密文、自己选择的密文消息以及相应的被解密的明文。
思路
如果两次加密的n1
和n2
具有相同的素因子,可以利用欧几里德算法
直接分解n1
和n2
.
通过欧几里德算法
计算出两个n
的最大公约数p
:
def gcd(a, b):
if a < b:
a, b = b, a
while b != 0:
temp = a % b
a = b
b = temp
def gcd_digui(a, b):
if b != 0:
return a
return gcd(b,a%b)
p = gcd(n1,n2)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
识别
识别此类题目,通常会发现题目给了若干个n,均不相同,并且都是2048bit,4096bit级别,无法正面硬杠,并且明文都没什么联系,e也一般取65537。
例题
n1=9051013965404084482870087864821455535159008696042953021965631089095795348830954383127323853272528967729311045179605407693592665683311660581204886571146327720288455874927281128121117323579691204792399913106627543274457036172455814805715668293705603675386878220947722186914112990452722174363713630297685159669328951520891938403452797650685849523658191947411429068829734053745180460758604283051344339641429819373112365211739216160420494167071996438506850526168389386850499796102003625404245645796271690310748804327
n2=13225948396179603816062046418717214792668512413625091569997524364243995991961018894150059207824093837420451375240550310050209398964506318518991620142575926623780411532257230701985821629425722030608722035570690474171259238153947095310303522831971664666067542649034461621725656234869005501293423975184701929729170077280251436216167293058560030089006140224375425679571181787206982712477261432579537981278055755344573767076951793312062480275004564657590263719816033564139497109942073701755011873153205366238585665743
直接分解成功。而欧几里得算法
的时间复杂度为:O(log n)。这个时间复杂度即便是4096 bit也是秒破级别
根据欧几里德算法
算出的p
之后,再用n
除以p
即可求出q
,由此可以得到的参数有p
、q
、n
、e
,再使用常规方法计算出d
,即可破解密文。
针对大整数的分解有很多种算法,性能上各有优异。
在p,q的取值差异过大,或者p,q的取值过于相近的时候,Format方法与Pollard rho方法都可以很快将n分解成功。
此类分解方法有一个开源项目yafu
将其自动化实现了,不论n的大小,只要p和q存在相差过大或者过近时,都可以通过yafu很快地分解成功。yafu
也有linux版本,但是我这存在一些问题装不上,能解决这个问题的大佬可以私信。
识别
不能直接分解n,不能使用公约数分解n,可以尝试yafu
。
在RSA
中的e
被称为加密指数。由于e
的选择只需要满足以下条件即可
计算欧拉函数 φ = (p-1) * (q-1),然后选择一个e(1<e<φ),并且e和φ互质
选择小的e
可以缩短加密时间,但是选择的e
不当,可能会造成严重的安全问题。
e=3的小明文攻击
当e=3
,并且明文过小时,导致明文的三次方仍然小于n
,通过直接对密文三次开方,即可得到明文。
原理如下
对明文m进行加密:c = pow(m, 3, N),可以得到密文c。
因为n > pow(m, 3),所以c = pow(m, 3, N) = pow(m, 3),故对密文三次开方,即可得到明文。
有一种特殊的情况是:pow(m, 3) > n,但是不是足够,假设存在这样的k,有下列的公式成立:
c = pow(m, 3) + k * n
爆破k
,当且仅当c - (k * n)
可以开三次方,c - (k * n)
开三次方结果就是明文m。
识别
当e=3时,优先使用这种方法解密。
i=0
while 1:
if(gmpy.root(c+i*N, 3)[1]==1):
print gmpy.root(c+i*N, 3)
break
i=i+1
- 1
- 2
- 3
- 4
- 5
- 6
与低加密指数类似,低解密指数可以加快解密的过程,但是这两者都带来了安全问题。
识别
e
看起来非常的大。
解题
直接github用工具就行。https://github.com/pablocelayes/rsa-wiener-attack
这里注意一个细节问题,如果在运行脚本的时候报错,请在脚本前加上:
import sys
sys.setrecursionlimit(10000000)
- 1
- 2
如果选取的加密指数e
比较低,并且使用了相同的加密指数e
给若干个接收者发送相同的信息,可以利用低加密指数广播攻击
得到明文。
选取相同的加密指数e
(例如e=3),对相同的明文m进行了加密并进行了消息的发送。有以下的等式成立。
c1 = pow(m, e, n1)
c2 = pow(m, e, n2)
c3 = pow(m, e, n3)
…
对上述等式运用中国剩余定理
,在e=3
时,可以得到
c_x = pow(m, 3, n1 * n2 * n3)
通过对 c_x进行三次开方可以得到明文。
识别
一般来说都是给了三组加密的参数和明密文,其中题目很明确地能告诉你这三组的明文都是一样的,并且e都取了一个较小的数字。
Coppersmith定理指出在一个e阶的mod n多项式f(x)中,如果有一个根小于n^frac{1}{e} ,就可以运用一个O(log n)的算法求出这些根。
这个定理可以应用于RSA算法。如果e = 3并且在明文当中只有三分之二的比特是已知的,这种算法可以求出明文中所有的比特
思路
根据欧拉函数
,可以通过p、q计算出欧拉函数值
φ(n) = (p-1) * (q-1)
之后再根据以下的公式反推出d
d * e ≡ 1 mod φ(N)
例题
http://www.shiyanbar.com/ctf/1828
在一次RSA密钥对生成中,假设p=473398607161,q=4511491,e=17
求解出d
将得到的d提交
根据思路可以python进行实现:
# 已知p、q、e求解d
import gmpy2
p = gmpy2.mpz(473398607161)
q = gmpy2.mpz(4511491)
e = gmpy2.mpz(17)
n = (p-1)*(q-1)
d = gmpy2.invert(e,n)
print("d is:\n%s"%d)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
思路
根据常规的思路,求解出明文m
,必须通过通过以下的公式
m ≡ pow(c,d) mod n
现在缺少的参数有d
、n
,其中的n
可以通过以下的公式可以求出
n = p * q
而d
可以通过以下公式求出
d * e = 1 mod φ(n)
φ(n) = (p-1) * (q-1)
例题
链接:http://ctf5.shiyanbar.com/crypto/rsarsa/rsa.txt
p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
Use RSA to find the secret message
根据上面的思路可以实现以下的python脚本
import gmpy2 p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483 q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407 e = 65537 c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034 # 1.已知的p和q求出n n = p * q # 2.根据已知的条件求出d phi_n = (p-1)*(q-1) d = gmpy2.invert(e,phi_n) #print(d) #求出明文 m = pow(c,d,n) print("m=\n%s"%m)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
思路
先根据
n = p * q
对已知的n进行大数分解得到p、q,一般通过在线或者自己通过脚本实现
根据欧拉函数
,可以通过p、q计算出欧拉函数值
φ(n) = (p-1) * (q-1)
之后再根据以下的公式反推出d
d * e ≡ 1 mod φ(N)
最后对密文c进行解密:m = pow(c, d, N),可以得到明文m。
例题
N=0xee290c7a603fc23300eb3f0e5868d056b7deb1af33b5112a6da1edc9612c5eeb4ab07d838a3b4397d8e6b6844065d98543a977ed40ccd8f57ac5bc2daee2dec301aac508f9befc27fae4a2665e82f13b1ddd17d3a0c85740bed8d53eeda665a5fc1bed35fbbcedd4279d04aa747ac1f996f724b14f0228366aeae34305152e1f430221f9594497686c9f49021d833144962c2a53dbb47bdbfd19785ad8da6e7b59be24d34ed201384d3b0f34267df4ba8b53f0f4481f9bd2e26c4a3e95cd1a47f806a1f16b86a9fc5e8a0756898f63f5c9144f51b401ba0dd5ad58fb0e97ebac9a41dc3fb4a378707f7210e64c131bca19bd54e39bbfa0d7a0e7c89d955b1c9f
e=0x10001
c=0x3dbf00a02f924a70f44bdd69e73c46241e9f036bfa49a0c92659d8eb0fe47e42068eaf156a9b3ee81651bc0576a91ffed48610c158dc8d2fb1719c7242704f0d965f8798304925a322c121904b91e5fc5eb3dc960b03eb8635be53b995217d4c317126e0ec6e9a9acfd5d915265634a22a612de962cfaa2e0443b78bdf841ff901423ef765e3d98b38bcce114fede1f13e223b9bd8155e913c8670d8b85b1f3bcb99353053cdb4aef1bf16fa74fd81e42325209c0953a694636c0ce0a19949f343dc229b2b7d80c3c43ebe80e89cbe3a3f7c867fd7cee06943886b0718a4a3584c9d9f9a66c9de29fda7cfee30ad3db061981855555eeac01940b1924eb4c301
先将n
转为10进制,可以通过一下的脚本
#16转10进制,n
n = int(0xee290c7a603fc23300eb3f0e5868d056b7deb1af33b5112a6da1edc9612c5eeb4ab07d838a3b4397d8e6b6844065d98543a977ed40ccd8f57ac5bc2daee2dec301aac508f9befc27fae4a2665e82f13b1ddd17d3a0c85740bed8d53eeda665a5fc1bed35fbbcedd4279d04aa747ac1f996f724b14f0228366aeae34305152e1f430221f9594497686c9f49021d833144962c2a53dbb47bdbfd19785ad8da6e7b59be24d34ed201384d3b0f34267df4ba8b53f0f4481f9bd2e26c4a3e95cd1a47f806a1f16b86a9fc5e8a0756898f63f5c9144f51b401ba0dd5ad58fb0e97ebac9a41dc3fb4a378707f7210e64c131bca19bd54e39bbfa0d7a0e7c89d955b1c9f)
print("n=\n%s"%n)
- 1
- 2
- 3
然后在线分解出p=57970027和q=518629368090170828331048663550229634444384299751272939077168648935075604180676006392464524953128293842996441022771890719731811852948684950388211907532651941639114462313594608747413310447500790775078081191686616804987790818396104388332734677935684723647108960882771460341293023764117182393730838418468480006985768382115446225422781116531906323045161803441960506496275763429558238732127362521949515590606221409745127192859630468854653290302491063292735496286233738504010613373838035073995140744724948933839238851600638652315655508861728439180988253324943039367876070687033249730660337593825389358874152757864093,在线地址http://www.factordb.com/index.php
#coding=utf-8 import gmpy2 from binascii import a2b_hex #n的16进制转10进制 n = int(0xee290c7a603fc23300eb3f0e5868d056b7deb1af33b5112a6da1edc9612c5eeb4ab07d838a3b #print("n=\n%s"%n) #通过在线分解出的p和q,以及给定的e,求出d e = gmpy2.mpz(int(0x10001)) p = 57970027 q = 5186293680901708283310486635502296344443842997512729390771686489350756041806760063 phi_n = (q-1)*(p-1) d = hex(gmpy2.invert(e,phi_n)) #print("d的十六进制为:\n%s"%d) #通过n,d,e,c求解明文 d = 0x9186c78d098af6815622ea9901cf84a89ead578a6dbdded7d7fc63531756239dc586501216fc2e4b e = 0x10001 c = 0x3dbf00a02f924a70f44bdd69e73c46241e9f036bfa49a0c92659d8eb0fe47e42068eaf156a9b3ee8 n = 0xee290c7a603fc23300eb3f0e5868d056b7deb1af33b5112a6da1edc9612c5eeb4ab07d838a3b4397 #flag = hex(pow(c,d,n))[1:].decoding("hex") flag = a2b_hex(hex(pow(c,d,n))[2:]) print(flag)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
思路
一般情况下,求解明文的公式为
m = pow(c, d, N)
在仅已知c
、e
的情况下,几乎不能反推出其他的参数,python中提供一个Crypto
的库,通过调用相关的函数模块,可以实现对n
、e
的求解,之后再通过分解大数n
等方法,求出其他的参数。
pycrypto
已经停止更新,推荐使用pycryptodome
安装命令 sudo pip3 install pycryptodome
例题
链接:http://www.shiyanbar.com/ctf/1772
首先通过公钥文件public.pem
获取n
、e
# 通过公钥文件获取n、e
from Crypto.PublicKey import RSA
public = RSA.importKey(open("./RSA/public.pem").read())
n = public.n
e = public.e
print("n=\n%s\ne=\n%s"%(n,e))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
n=
74207624142945242263057035287110983967646020057307828709587969646701361764263
e=
65537
通过在线网站
http://www.factordb.com/index.php?query=74207624142945242263057035287110983967646020057307828709587969646701361764263 分解n
可以得到p=258631601377848992211685134376492365269
以及q=286924040788547268861394901519826758027
生成私钥
#python2 from Crypto.PublicKey import RSA keypair = RSA.generate(1024) keypair.p = 258631601377848992211685134376492365269 keypair.q = 286924040788547268861394901519826758027 keypair.e = 65537 keypair.n = keypair.p * keypair.q phi_n = (keypair.p-1) * (keypair.q-1) i = 1 while (True): x = (phi_n * i ) + 1 if (x % keypair.e == 0): keypair.d = x / keypair.e break i += 1 private = open('private.pem','w') private.write(keypair.exportKey()) private.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
最后使用生成的私钥将加密文件解密
openssl rsautl -decrypt -in ./RSA/flag.enc -inkey private.pem -out flag.txt
d
求解d
一般的除了可以利用gmpy2
模块的gmpy2.invert(e,phi_n)
函数之外,还可以利用 扩展欧几里德算法
计算出d
,以下是python
的实现:
#coding:utf-8 def egcd(a, b): #扩展欧几里德算法 if a == 0: return (b, 0, 1) else: g, y, x = egcd(b % a, a) return (g, x - (b // a) * y, y) def modinv(a, m): #d=modinv(e,(p-1)*(q-1)) g, x, y = egcd(a, m) if g != 1: raise Exception('modular inverse does not exist') else: return x % m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
例如第一题可以这样求解:
#coding:utf-8 p=47339860716 q=4511491 e=17 def egcd(a, b): #扩展欧几里德算法 if a == 0: return (b, 0, 1) else: g, y, x = egcd(b % a, a) return (g, x - (b // a) * y, y) def modinv(a, m): #d=modinv(e,(p-1)*(q-1)) g, x, y = egcd(a, m) if g != 1: raise Exception('modular inverse does not exist') else: return x % m d = modinv(e,(p-1)*(q-1)) print("d=\n%s"%d)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
部分参考其他大佬的文章,CTF和网安道路还很远,共勉。有兴趣的可以联系我,一起学习交流。
参考的文章包括但是不限于这些:
RSA脚本总结请移步我的另一篇博文
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。