NSSCTF Round#11 Basic 密码学专场

发布时间 2023-04-08 19:16:30作者: Sone070805

闲来无事很久没做题了做一做这次的密码学专场,简单记录一下

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}