crypto
fake_n
from Crypto.Util.number import *
from secret import flag
def fakeN_list():
puzzle_list = []
for i in range(15):
r = getPrime(32)
puzzle_list.append(r)
p = getPrime(32)
q = getPrime(32)
com = p*q
puzzle_list.append(com)
return puzzle_list
def encrypt(m,e,fake_n_list):
fake_n = 1
for i in range(len(fake_n_list)):
fake_n *= fake_n_list[i]
really_n = 1
for i in range(len(fake_n_list)-1):
really_n *= fake_n_list[i]
c = pow(m,e,really_n)
print("c =",c)
print("fake_n =",fake_n)
if __name__ == '__main__':
m = bytes_to_long(flag)
e = 65537
fake_n_list = fakeN_list()
encrypt(m,e,fake_n_list)
'''
c = 6451324417011540096371899193595274967584961629958072589442231753539333785715373417620914700292158431998640787575661170945478654203892533418902
fake_n = 178981104694777551556050210788105224912858808489844293395656882292972328450647023459180992923023126555636398409062602947287270007964052060975137318172446309766581
'''
观察代码,首先生成15个32位素数作为列表,com为怕p,q两个素数的乘积,添加到puzzle列表
然后生成fack_n,假的,真的为列表减一生成的,接着常规加密,给了c和fack_n
分解fack_n
得到17个素数,而真的为list减一也就是15个(com为p*q),遍历得到真的list,接着常规解密。
exp:
from itertools import combinations
from math import prod
from Crypto.Util.number import *
# 给定的17个数
numbers = [2215221821, 2290486867, 2333428577, 2361589081, 2446301969, 2507934301,
2590663067, 3107210929, 3278987191, 3389689241, 3417707929, 3429664037,
3716624207, 3859354699, 3965529989, 4098704749, 4267348123]
# 计算所有15个数的乘积
for combo in combinations(numbers, 15):
product_result = prod(combo)
e = 65537
phi = 1
for num in combo:
phi *= (num - 1)
d = inverse(e, phi)
n = product_result
c = 6451324417011540096371899193595274967584961629958072589442231753539333785715373417620914700292158431998640787575661170945478654203892533418902
m = pow(c, d, n)
if b'begin' in long_to_bytes(m):
print(long_to_bytes(m))
菜鸡一个就会一道。
接下来的是看大佬wp学习的
我玩青水的
from Crypto.Util.number import *
from secret import flag
m = bytes_to_long(flag)
e = 2
p = getPrime(512)
c = pow(m, e, p)
print(f"p = {p}")
print(f"c = {c}")
'''
p = 7709388356791362098686964537734555579863438117190798798028727762878684782880904322549856912344789781854618283939002621383390230228555920884200579836394161
c = 5573755468949553624452023926839820294500672937008992680281196534187840615851844091682946567434189657243627735469507175898662317628420037437385814152733456
'''
看到e为2,想到去爆破
c_e = c + k*n
m = iroot(c_e, e)
无果,跑了好久没有解出来。
看大佬的wp,使用二次剩余
from Crypto.Util.number import long_to_bytes
from sympy import legendre_symbol, sqrt_mod
p = 7709388356791362098686964537734555579863438117190798798028727762878684782880904322549856912344789781854618283939002621383390230228555920884200579836394161
c = 5573755468949553624452023926839820294500672937008992680281196534187840615851844091682946567434189657243627735469507175898662317628420037437385814152733456
assert legendre_symbol(c, p) == 1
m = sqrt_mod(c, p)
print(long_to_bytes(m).decode())
公式x^2≡a(mod p),即m^e≡c(mod p),所以m就为c mod p 再开e次方。
又新学了一个知识:二次剩余
Hard_ECC
from Crypto.Util.number import *
A = [0, 3, 0, 973467756888603754244984534697613606855346504624, 864199516181393560796053875706729531134503137794]
p = 992366950031561379255380016673152446250935173367
ec = EllipticCurve(GF(p), [A[0], A[1], A[2], A[3], A[4]])
print(ec)
T = ec(295622334572794306408950267006569138184895225554, 739097242015870070426694048559637981600496920065)
Q = ec(282367703408904350779510132139045982196580800466, 411950462764902930006129702137150443195710071159)
flag = T.discrete_log(Q)
print(long_to_bytes(flag)[::-1])
ECC解密,新知识。
PAD
使用CAT中国剩余定理解
from Crypto.Util.number import * from gmpy2 import *
n1, e1, cipher1 = (66774173046867106978564392807774188269534394449840296405910777832911685835495393323180077968974708562688760938291099725499683301622430513476820311716679706861971145656513111211588447567157066572973454278697174902701179905913830295650932313907414913975102061018460218742766703308850479537206120634422169081427, 1, (3, 9947849848628394040911390578513458759307204504154925933108800760285314551328261356068666838417233200825260136676377138010240930409364211389785744843760837346711809102522170726809372344662827652364290577950806740613036994404769812936985438300111324782034383266110793322048638372472511933383991308991836303085))
n2, e2, cipher2 = (106767898023371218423152864353657990206786844053323081814367566137791462861076105612953165101095459965355888579793001990295079328576934744471072610716783059331039361374403506527014277102323143521611845402119843273520129773940304491841977534175178588819814003499404957816785446454296240881137075499584543716543, 1, (3, 89474175499710650627045495122991228821208419287337065022608137539886067322214114776519065277932934505966581338351557710626859066870067797237993034195327754930798089606782234426788890149635194335859611625615400875535638986318875397799112650671284135301549889548440675440686889599236878052391294453286500547277))
e = e1
pad_e = cipher1[0]
c1 = cipher1[1]
c2 = cipher2[1]
print(e)
n_list = [n1, n2]
c_list = [c1 % n1, c2 % n2]
c = crt(c_list, n_list)
c = c - (pad_e ** 511)
m = iroot(c, pad_e)
print(m[1])
print(long_to_bytes(m[0]))
CAT:
def Get_Mi(m_list, M):
M_list = []
for mi in m_list:
M_list.append(M // mi)
return M_list
def Get_ei_list(M_list, m_list):
ei_list = []
for i in range(len(M_list)):
ei_list.append(Get_ei(M_list[i], m_list[i])[0])
return ei_list
def Get_ei(a, b):
if 0 == b:
x = 1;
y = 0;
q = a
return x, y, q
xyq = Get_ei(b, a % b)
x = xyq[0];
y = xyq[1];
q = xyq[2]
temp = x;
x = y;
y = temp - a // b * y
return x, y, q
def crt(a_list, m_list):
M = 1
for mi in m_list:
M *= mi
Mi_list = Get_Mi(m_list, M)
Mi_inverse = Get_ei_list(Mi_list, m_list)
x = 0
for i in range(len(a_list)):
x += Mi_list[i] * Mi_inverse[i] * a_list[i]
x %= M
return x
if __name__ == '__main__':
a_list = list(map(int, input().split(",")))
m_list = list(map(int, input().split(",")))
print(crt(a_list, m_list))
CRT2:
def exgcd(a, b) :
if b == 0 :
return 1, 0, a
x, y, d = exgcd(b, a % b)
return y, x - (a // b) * y, d
def CRT(a, b) : #a, b分别是模数和余数
M = 1
X = 0
for i in a :
M *= i
for i in zip(a, b) :
w = M // i[0]
x, y, d = exgcd(w, i[0])
X = (X + x * w * i[1]) % M
return (X % M + M) % M
以前了解过中国剩余定理,不怎么会用,现在会了。
剩下的以后再学,膜拜大佬。
misc
记录一下难的,不好猜的
devil's word
leu lia leu ng leu cai leu jau leu e cai b cai jau sa leng cai ng ng f leu b leu e sa leng cai cai ng f cai cai sa sa leu e cai a leu bo leu f cai ng ng f leu sii leu jau sa sii leu c leu ng leu sa cai sii cai d
才开始以为是特殊编码,搜索无果,后面才知道是温州话》》》》》
with open("devil's word.txt", 'r') as f:
data = f.read().strip().split(' ')
table = {
'leng': '0', 'lia': '2', 'sa': '3', 'sii': '4', 'bo': '8',
'ng': '5', 'leu': '6', 'cai': '7', 'jau': '9',
'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd', 'e': 'e', 'f': 'f'}
result = b''
for i in range(0, len(data), 2):
result += bytes([int(table[data[i]]+table[data[i + 1]], 16)])
print(result.decode())
你知道中国文化嘛 1.0
base32解题以后得到残缺的八卦,最开始想到转二进制,无果,搜索发现可以为0-7,转码后解得社会主义编码
def bArrToStr(bArr):
nByte = b''
for b in bArr:
nByte += chr(int(b,base=8)).encode('raw_unicode_escape')
return bytes.decode(nByte)
def to8bArr(baguaStr):
code = {'☰':'0', # 乾
'☱':'1', # 兑
'☲':'2', # 离
'☳':'3', # 震
'☴':'4', # 巽
'☵':'5', # 坎
'☶':'6', # 艮
'☷':'7', # 坤
}
bArr = []
temp = []
# 把八卦符转为8进制数字
for s in baguaStr:
temp.append(code[s])
tempStr = ''
for i in range(len(temp)):
tempStr += temp[i]
if i % 3 == 2:
bArr.append('0o'+tempStr)
tempStr = ''
八卦图形base64 (github.com/chyroc/base8-bagua)工具链接
根据两个图形的接触点判断.-/,然后摩斯密码解密,脑洞真的大。
标签:总结,Beginctf,list,cai,leu,fake,print,import,赛后 From: https://www.cnblogs.com/huicry/p/18009771