NSSCTF Round#11 Basic 密码学专场
闲来无事很久没做题了做一做这次的密码学专场,简单记录一下
ez_enc
题目提示了不是培根密码,然后只出现了AB并且没有间隔,猜想是二进制,将A变为0,B变为1,转字符串就能够得到flag
MyGame
from Crypto.Util.number import * import os import random import string flag = os.getenv('FLAG') def menu(): print('''=---menu---= 1. Guess 2. Encrypt ''') p = getPrime(512) q = getPrime(512) n = p*q def randommsg(): return ''.join(random.choices(string.ascii_lowercase+string.digits, k=30)) mymsg = randommsg() def guess(): global mymsg msg = input() if msg == mymsg: print(flag) else: print(mymsg) mymsg = randommsg() def encrypt(): e = random.getrandbits(8) c = pow(bytes_to_long(mymsg.encode()), e, n) print(f'Cipher_{e}: {c}') def main(): print(f'n: {n}') while True: opt = int(input()) if opt == 1: guess() elif opt == 2: encrypt() main()
比较常见的一个共模攻击,按2可以获取e,c,我们获取两组e,c就可以使用共模攻击解rsa了,然后按1和环境交互一下获取flag
n= 104053546280146086895263266004854627864129791423986559376155631939659146873757995751744064139106264341084410067188940484154180363243925641188081530145072287600512016277096817784199472363136994060747399745320597829304930737961144113196749085603728098872505242513445498595416180801797673993509366522179636919871 c1= 29061081326071851776243306913519767710233722869921686932292413308188986973233086309680703863976759707962319411640308373631606483479357305197536440692785110465592067653674111506728173037148537164372529109250972584411097480949383090571322277439584545569283740256792538902920163151700697008045191055455153963388 c2= 48856376272714191352021436873522391210392822998143798763272682798576592124680002932827447189769345930490352486161720901733346625828557301335191908507795186181330466474483408247838279158989328658546989738424703391401401513216676564784975559020378649065194777275611558457261587139423315811645260292985527436575 e1=139 e2=179 from gmpy2 import gcdext, iroot from Crypto.Util.number import long_to_bytes g,x,y=gcdext(e1,e2) m=pow(c1,x,n)*pow(c2,y,n)%n print(long_to_bytes(m)) #9z1rj1v6cwyl4igky7niuen9sk2v98
MyMessage
题目代码:
from Crypto.Util.number import * import os flag = os.getenv('FLAG') e = 127 def sign(): msg = input("Input message:") p = getPrime(512) q = getPrime(512) n = p*q c = pow(bytes_to_long((msg + flag).encode()), e, n) print(f"n: {n}") print(f"Token: {hex(c)}") def main(): while True: sign() main()
这个也是RSA中间比较常考的一个类型,广播攻击,因为e=127,所以写个脚本获取127组数据然后使用中国剩余定理求解
from pwn import * r=remote('node2.anna.nssctf.cn',28395) c=[] n=[] for i in range(127): print(i) r.recv() r.sendline(b'a') n.append(int(r.recvline()[2:-1])) c.append(int(r.recvline()[7:-1],16)) import gmpy2 from functools import reduce from Crypto.Util.number import * 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) ans=chinese_remainder(n, c) ans=gmpy2.iroot(ans,127)[0] print(long_to_bytes(ans)) #NSSCTF{4f747d25-5170-481d-9e43-6b3873363d48}
ez_signin
题目代码:
from Crypto.Util.number import * from secret import flag p = getPrime(512) q = getPrime(512) assert p > q n = p*q e = 65536 m = bytes_to_long(flag) num1 = (pow(p,e,n)-pow(q,e,n)) % n num2 = pow(p-q,e,n) c = pow(m,e,n) print("num1=",num1) print("num2=",num2) print("n=",n) print("c=",c)
第一步分解n就是一个公式的推导
接下来我们观察到e=65536也就是2的16次方,所以我们可以通过求解16次的rabin去求解flag
num1= 44206098867921683934417336928985233025588668574343656117948540310110160027490983465415295177743546580694164644832046493330614725811380213519602775631490351664564138310053844939631114079065200612184580240438753793686596989511468932557217502300794435521797743787140897559589105842948072603012026732015159248161 num2= 13158554656623888251824342126888607296067884540206118434955743058207129333043696077566891529996443016879725943567450351660563839393324019719008854051662141369878552172587549722070113268453351045007269083352241057488869085531749477212341631467982511665359513684209818635259722897425450783278277211506057798953 n= 79495062269474059086610613577653461910599876749939821437096699098249180733016958347986361199400546365733098911391037456170325538796659332027061077293239358103033820573421427489291236167744598406251949902736785724133465146856453942849365511326183495398523343220715512931188931073129826736676070363871532058109 c= 78298975734843045778143611287902361805173888506727676771128811291335684212793777448528291817658781055139497267284952107724635579920126188479830442375942623845306975960733313270523277119682271415799574929673202157230774136292774956846148838799371832656652762824040928434071621787980715438170808189641131633842 import gmpy2 from Crypto.Util.number import * a=(num2-num1)%n q=gmpy2.gcd(a,n) p=n//q def rabin_decrypt(c, p, q, e=2): n = p * q mp = pow(c, (p + 1) // 4, p) mq = pow(c, (q + 1) // 4, q) yp = gmpy2.invert(p, q) yq = gmpy2.invert(q, p) r = (yp * p * mq + yq * q * mp) % n rr = n - r s = (yp * p * mq - yq * q * mp) % n ss = n - s return (r, rr, s, ss) for i in range(16): w,b,c,d=rabin_decrypt(c,p,q) print(long_to_bytes(b)) #NSSCTF{6bcf361d-b371-4869-83f8-ac1682546933}
NTR
题目代码:
import gmpy2 from flag import flag from Crypto.Util.number import * def init(): p = getPrime(2048) while True: x = getRandomNBitInteger(1024) y = getPrime(768) z = gmpy2.invert(x, p) * y % p return (p, x, y, z) def encrypt(cipher, p, z): message = bytes_to_long(cipher) r = getRandomNBitInteger(1024) c = (r * z + message) % p return c p, x, y, z = init() c = encrypt(flag, p, z) with open("cipher.txt", "w") as f: f.write("binz = " + str(bin(z)) + "\n") f.write("binp = " + str(bin(p)) + "\n") f.write("binc = " + str(bin(c)) + "\n")
这个题其实是一个基础的NTRU格密码,看懂了原理直接做就好,这里就不多说了想看原理的师傅们可以搜索一下推导过程
h = 0b1000100010101000111011000010101011111011100110000100100101100100011011111110101100101000000000111111001110101010111101100110011010101100111111110111010100111101011011101000111111010100100100110100111110001101000000011000101010011110000011111110101111010110010000010110101100011111101100011100100000011011100110111011001101111110011001000101110100001101110110100000100001100110010010110011011000000110111101011101010101110010010111111111101111001100000111001110011101011010100000101011010001110010101100000101011111001111111010110110101100011000100111000010010011000111110111100101101101000100000011100011100000011011001011101001011100111010101011110111010010001000010110101110110110001111000111101000110001110001000000010101001001101101010111011010010010111110010101000110010001110010100110101010101110011110100011100000011010011100110101110000111101010100000100101010111101000010101101111011111001100010010011101101001001000100010100011001010101010111110010101100011110110010111101001010000101001011110111111100000000101011010011101101110011000000011100000000000111111111010001101111100010000110101101011100000000100000001110101001100111011100001011001110010001000101000001110000001101000101011000011100110101111111111011100010110011101111101111100011111100001110101110011011100011100100100010110011000100010111010010111110111111000100011001000110001010111001100001101101111001110100010001111101010101110110001101100101101100100001101101100000011101100010101011011111000111001000000011000011101010111100100011100011110000011010110100010111011001110110001101001010110010000110100011110100011001000100011110101100101101111011111000100111110111010011010110011011100100001000001001110000010100001010101110001011010111111101111100110000101111101011110111110010011100010110011000011110110001000110010101011001110010111001110111010101110100000100000110011110111000111001101101101110010001001101010010000010100110010110001100100111101101101100011111001011011010111011001011111111000110011110000101001110110100101111010101001111110100001011011011111011001 p = 0b11010101111001010101010111110000001101100011100000011000110101001110001100001101111001110101111111110000111000001011010011011010101110101101010101110010011110111100001100001000100100111110110011000111011110100101100100010110001101110101110111101101011001000001110100100101110101010100100000100010110011111111001000101001010101111101101110110111111001110011101000010001011010100111011001111000111000101110110110100110011010101110100011010000000001001110011110011001111010111011100111000101110101110111001101000001101001111001100001000111011000001000001000101101011100010110011010010110110100000100010100010100011100100101010110110100111100000001111111000010100110000101101001011110101100010001011101100000100001011111101011101000111100001010111100110110111011001110001010001101011011100001111000110000100101100100111010000001101000010111100100011101010010010010000011110110000100010001100010111000010110001010101011001001001011101010111101100110000110010101110111001111101100111110101001001000000011010111010000111110011110101010000110100000000111110111000101000001100110011010000011111010001000011001001000101101000101000110011011101010111000100111110001111111111110110010010010111111101101101100010101000010010111101100010100000011111111100011101110100100010011000110010000100011010010111010000101110001110111000110011111010001101000000000110111100100011011111110010111001100100110000010110010010111001110111101001011000011010010111100111101000100110000010110001011110001110000111000110001110101100100010011101010010010100000000110101010110000010001011110011100111000011011000001010111111010101011100100110110011111111000010101001111110011001011110101101110010000101000110100010101010001000001000000001110110101011001100010001100010001111111100101000110101110111001010001101010000110111001010011001010000101011101011011010100101100100111011110011010000110101111100000110101000011110101100000011110110101011100001110010010110001111000010011111010100101011101110111000110010000101010101000100111011010000110000111101111000110000000001010111011011111 c = 0b1100111111101000011010101110010011000001010011110001111011110001100100111110111110010110011000010011001000001101101110010000001110000010011101011110011100110110100001111010101011011100010001101011001100011011101000100101110011111110110100000000010000111110110010000001111000111011101100110001001001101010101101001010010101011010010110010001111101000110101100100010100010100000101000000011000101011010011010101110001000010010101100100010000010110010101011010111000100100100011010101001110101100101111011011100001100101100101010011001011101011100010111100100001100010000110100100100010110010001101010001000001010010101000010101100101000000110000001100101111110000001010111101001001100100100100010100001010000100010001011001010100010000000111111011101111000010000011001110101011010110110010110001010110100000100011010101001001011111111001110000010001111100110001101100000000101011010011001011101011011110000001110000111000101100111111101101001000001110000110010111101111101001001100010110010101110111000000001010110101111110111000000000000001101011111101110111111110110010011100001001100001100101001100001010110100101100010011101110110000010001100010000110110001101001111100011111011110000110010000101101000001000001010100110111100011100101010110101000010101101000001101000011010000111000110100111100001000010101100110111100010100100111110100010110110000000001111010101110111111001111111110010000111111010000001010011000101011001101111101111000101010111011001000010101011000101110001000110001011011010010001010011000011111010000101100001011000000010001001000010001111101100011011000100001000101000010010010110000100000000001101011010000000010001001110000000010111001011000000001001000100100100001110110001111110111011010100000000111001010010101111101011010000110111001110100100001111111101100100011000111110000000100100111001100000100011010010010001010100001110110010110010101101001110111110000010100000010000110000101111101010000100101001111110001110111011010010111100101101000010100010000000010111110010011111111011110101101001111010111010101011000 from Crypto.Util.number import * import gmpy2 def GaussLatticeReduction(v1, v2): while True: if v2.norm() < v1.norm(): v1, v2 = v2, v1 m = round( v1*v2 / v1.norm()^2 ) if m == 0: return (v1, v2) v2 = v2 - m * v1 # Construct lattice. v1 = vector(ZZ, [1, h]) v2 = vector(ZZ, [0, p]) m = matrix([v1,v2]); # Solve SVP. shortest_vector = m.LLL()[0] # shortest_vector = GaussLatticeReduction(v1, v2)[0] f, g = shortest_vector print(f) print("----------------------------------------------------") print(g) f = abs(f) g = abs(g) # Decrypt. a = f * c % p % g m = a * inverse_mod(f , g) % g print(long_to_bytes(int(m))) #NSSCTF{8c9e74d9-0fe8-40dd-b5b3-4d48dccc0eab}
ez_fac
题目代码:
from Crypto.Util.number import * import random from secret import flag,a0,a1,b0,b1 p = getPrime(512) q = getPrime(512) e = getPrime(128) n = p*q assert pow(a0,2) + e * pow(b0,2) == n assert pow(a1,2) + e * pow(b1,2) == n m = bytes_to_long(flag) c = pow(m,e,n) print("c=",c) print("n=",n) print("a0=",a0) print("a1=",a1) print("b0=",b0) print("b1=",b1)
这个题主要就是涉及到一个构造去分解n,找到一篇论文里面有提到这种类型的题,对论文里的方法实现一下就好
c= 269919338399778514189097962459678434783724673741730080674353873855765412154875993557715430564959240474049809871157613287407079971279213930956687778294551579955984720444524569811914884347687368540763491777259461861923563801119795460942970390631507260406090468096709799521038984083575447132830798336850094278 n= 82692378663674258454167916809507984892487250304668801955152221991573597887250877903288194234981588117516025136975959615769735794887852435054097551643555833839425523182113446373620869917232315959702904208899966367161295365559365171640839633750987416091496572818773280657708013794589205943221152585023911671559 a0= 9093534992711814404467034402883060492209315197587999313919901009972929023541781949624426602759491034644719384555752652664740847850655499849175726882533386 a1= 9093534992711814404467033529304036852626828940370599085022757849038626779909496845240221198777109383170882880712576498364185809858970352094050511026366694 b0= 25325478115881052887279924356886411516024638175732281357719448726546734460979429253586888487790093572149108696694577729233 b1= 256076424668018487565047687817893686584821196831199588134389308371927699019810811905473631001332765976816230970903537766287 e=(n-pow(a0,2))//pow(b0,2) import gmpy2 p=gmpy2.gcd(n,b1*a0-b0*a1) q=n//p d=gmpy2.invert(e,(p-1)*(q-1)) m=pow(c,d,n) from Crypto.Util.number import * print(long_to_bytes(m)) #NSSCTF{8c0ea3e1-4f24-4c3d-8b52-2915c42abeee}