cryptohack RSA部分
1.Salty:
此题为rsa加密中e=1的情况,由于\(ed(mod phi)=1\),所以d自然是等于1的,不用分解n就解出了d
from Crypto.Util.number import long_to_bytes
e=1
k=1
ct=44981230718212183604274785925793145442655465025264554046028251311164494127485
n=110581795715958566206600392161360212579669637391437097703685154237017351570464767725324182051199901920318211290404777259728923614917211291562555864753005179326101890427669819834642007924406862482343614488768256951616086287044725034412802176312273081322195866046098595306261781788276570920467840172004530873767
d=1
pt=pow(ct,d,n)
print(long_to_bytes(pt))
crypto{saltstack_fell_for_this!}
2.Modulus Inutilis
此题的e=3,直接低加密指数攻击,网上脚本很多
from gmpy2 import iroot
import libnum
e = 3
n = 17258212916191948536348548470938004244269544560039009244721959293554822498047075403658429865201816363311805874117705688359853941515579440852166618074161313773416434156467811969628473425365608002907061241714688204565170146117869742910273064909154666642642308154422770994836108669814632309362483307560217924183202838588431342622551598499747369771295105890359290073146330677383341121242366368309126850094371525078749496850520075015636716490087482193603562501577348571256210991732071282478547626856068209192987351212490642903450263288650415552403935705444809043563866466823492258216747445926536608548665086042098252335883
c = 243251053617903760309941844835411292373350655973075480264001352919865180151222189820473358411037759381328642957324889519192337152355302808400638052620580409813222660643570085177957
k = 0
while 1:
res = iroot(c+k*n,e) #c+k*n 开3次方根 能开3次方即可
if(res[1] == True):
print(libnum.n2s(int(res[0]))) #转为字符串
break
k=k+1
crypto{N33d_m04R_p4dd1ng}
3.Everything is Big
e很大的情况,可以使用维纳攻击,基于连分数的攻击方法
import gmpy2
from Crypto.Util.number import long_to_bytes
def transform(x, y): # 使用辗转相处将分数 x/y 转为连分数的形式
res = []
while y:
res.append(x // y)
x, y = y, x % y
return res
def continued_fraction(sub_res):
numerator, denominator = 1, 0
for i in sub_res[::-1]: # 从sublist的后面往前循环
denominator, numerator = numerator, i * numerator + denominator
return denominator, numerator # 得到渐进分数的分母和分子,并返回
# 求解每个渐进分数
def sub_fraction(x, y):
res = transform(x, y)
res = list(map(continued_fraction, (res[0:i] for i in range(1, len(res))))) # 将连分数的结果逐一截取以求渐进分数
return res
def get_pq(a, b, c): # 由p+q和pq的值通过维达定理来求解p和q
par = gmpy2.isqrt(b * b - 4 * a * c) # 由上述可得,开根号一定是整数,因为有解
x1, x2 = (-b + par) // (2 * a), (-b - par) // (2 * a)
return x1, x2
def wienerAttack(e, n):
for (d, k) in sub_fraction(e, n): # 用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数
if k == 0: # 可能会出现连分数的第一个为0的情况,排除
continue
if (e * d - 1) % k != 0: # ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n)
continue
phi = (e * d - 1) // k # 这个结果就是 φ(n)
px, qy = get_pq(1, n - phi + 1, n)
if px * qy == n:
p, q = abs(int(px)), abs(int(qy)) # 可能会得到两个负数,负负得正未尝不会出现
d = gmpy2.invert(e, (p - 1) * (q - 1)) # 求ed=1 (mod φ(n))的结果,也就是e关于 φ(n)的乘法逆元d
return d
print("该方法不适用")
c =
e =
n =
d = wienerAttack(e, n)
print("d=", d)
m = pow(c, d, n)
print(long_to_bytes(m))
crypto{s0m3th1ng5_c4n_b3_t00_b1g}
4.Crossed Wires
题目给出了e、d和N,由于\(ed(mod\varphi)=1\),故\(ed=k\varphi+1\),又因为\(N=p*q\),\(\varphi=(p-1)\times(q-1)\),故N和\(\varphi\)是一个很接近的数,因此\(k=\frac{ed}{N}+1\),\(\varphi =\frac{ed-1}{k}\),因此我们就得到了\(\varphi\)
题干:
import gmpy2
from Crypto.Util.number import getPrime, long_to_bytes, bytes_to_long, inverse
import math
from gmpy2 import next_prime
FLAG = b"crypto{????????????????????????????????????????????????}"
p = getPrime(1024)
q = getPrime(1024)
N = p*q
phi = (p-1)*(q-1)
e = 0x10001
d = inverse(e, phi)
my_key = (N, d)
friends = 5
friend_keys = [(N, getPrime(17)) for _ in range(friends)]
cipher = bytes_to_long(FLAG)
for key in friend_keys:
cipher = pow(cipher, key[1], key[0])
print(f"My private key: {my_key}")
print(f"My Friend's public keys: {friend_keys}")
print(f"Encrypted flag: {cipher}")
可以发现明文被五组(e,N)加密了五次,我们拿到了\(\varphi\),就可以求出每组的d了,就可以完成解密
exp:
e = 0x10001
N = 21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771
d = 2734411677251148030723138005716109733838866545375527602018255159319631026653190783670493107936401603981429171880504360560494771017246468702902647370954220312452541342858747590576273775107870450853533717116684326976263006435733382045807971890762018747729574021057430331778033982359184838159747331236538501849965329264774927607570410347019418407451937875684373454982306923178403161216817237890962651214718831954215200637651103907209347900857824722653217179548148145687181377220544864521808230122730967452981435355334932104265488075777638608041325256776275200067541533022527964743478554948792578057708522350812154888097
k = e * d // N + 1
print(k)
phi = (e * d - 1) // k
print(phi)
print((e * d) % phi)
c = 20304610279578186738172766224224793119885071262464464448863461184092225736054747976985179673905441502689126216282897704508745403799054734121583968853999791604281615154100736259131453424385364324630229671185343778172807262640709301838274824603101692485662726226902121105591137437331463201881264245562214012160875177167442010952439360623396658974413900469093836794752270399520074596329058725874834082188697377597949405779039139194196065364426213208345461407030771089787529200057105746584493554722790592530472869581310117300343461207750821737840042745530876391793484035024644475535353227851321505537398888106855012746117
Ne = [(
21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771,
106979), (
21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771,
108533), (
21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771,
69557), (
21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771,
97117), (
21711308225346315542706844618441565741046498277716979943478360598053144971379956916575370343448988601905854572029635846626259487297950305231661109855854947494209135205589258643517961521594924368498672064293208230802441077390193682958095111922082677813175804775628884377724377647428385841831277059274172982280545237765559969228707506857561215268491024097063920337721783673060530181637161577401589126558556182546896783307370517275046522704047385786111489447064794210010802761708615907245523492585896286374996088089317826162798278528296206977900274431829829206103227171839270887476436899494428371323874689055690729986771,
103231)]
for i in Ne:
e_ = i[1]
d_ = gmpy2.invert(e_, phi)
m = pow(c, d_, N)
c = m
print(long_to_bytes(m))
crypto{3ncrypt_y0ur_s3cr3t_w1th_y0ur_fr1end5_publ1c_k3y}
5.Everything is Still Big
用第三题的wienerAttack(维纳攻击)秒了
crypto{bon3h5_4tt4ck_i5_sr0ng3r_th4n_w13n3r5}
6.Endless Emails
e=3,给出了多组的n,c
exp:
import gmpy2
from Crypto.Util.number import *
e=3
c=[]
n=[]
from functools import reduce
def chinese_remainder(n, a):#
sum = 0
prod = reduce(lambda a, b: a * b, n)
for n_i, a_i in zip(n, a):
p = prod // n_i
sum += a_i * gmpy2.invert(p, n_i) * p
return int(sum % prod)
for i in range(len(n)):
for j in range(len(n)):
for k in range(len(n)):
if (i!=j)&(i!=k)&(j!=k):
M=chinese_remainder([n[i],n[j],n[k]],[c[i],c[j],c[k]])
m = gmpy2.iroot(M,3)[0]
print(long_to_bytes(m))
crypto{1f_y0u_d0nt_p4d_y0u_4r3_Vuln3rabl3}
7.Infinite Descent
FLAG = b"crypto{???????????????????}"
def getPrimes(bitsize):
r = random.getrandbits(bitsize)
p, q = r, r
while not isPrime(p):
p += random.getrandbits(bitsize//4)
while not isPrime(q):
q += random.getrandbits(bitsize//8)
return p, q
m = bytes_to_long(FLAG)
p, q = getPrimes(2048)
n = p * q
e = 0x10001
c = pow(m, e, n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
可以发现pq挨得很近,把n直接用factordb分解了(也可以使用yafu),然后直接rsa解密即可
crypto{f3rm47_w45_4_g3n1u5}