naby

导航

0xGame2024-week1-crypto

Crypto

Caesar Cipher

密文:0yHbnf{Uif_Cfhjoojoh_Pg_Dszqup}

提示:凯撒加密。

改成-1就好了

RSA_Easy

from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5
from random import randint
from gmpy2 import invert,gcd

#Hash Functi
on:
def MD5(m):return md5(str(m).encode()).hexdigest()

#RSA AlgorithmParameter Generation Function:
def KeyGen():
	Factor_BitLength = 30
	q = getPrime(Factor_BitLength)
	p = getPrime(Factor_BitLength)
	N = p * q
	#Euler's totient function:
	phi = (p-1) * (q-1)

	#Generate Keys:
	while True:
		e = randint(1,phi)
		if gcd(e,phi) == 1:
			break

	#Generate Result:
	Pub_Key = (N,e)
	return Pub_Key

Pub = KeyGen()

N = Pub[0]
e = Pub[1]

#RSA Encrypt:
m = randint(1,N)
c = pow(m,e,N)

print(f'Pub_Key = {Pub}')
print(f'Encrypt_msg = {c}')

直接网站分解就行了

from Crypto.Util.number import *
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()

Pub_Key = (689802261604270193, 620245111658678815)
Encrypt_msg = 289281498571087475

# factordb
p=823642439
q=837502087
m=pow(Encrypt_msg,inverse(Pub_Key[1],(p-1)*(q-1)),p*q)

flag = '0xGame{'+ MD5(m) +'}'
print(flag)
# 0xGame{5aa4603855d01ffdc5dcf92e0e604f31}

RSA-Baby

from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5
from random import randint
from gmpy2 import invert,gcd

#Hash Function:
def MD5(m):return md5(str(m).encode()).hexdigest()

#RSA AlgorithmParameter Generation Function:
def KeyGen():
	Factor_BitLength = 30
	q = getPrime(Factor_BitLength)
	p = getPrime(Factor_BitLength)
	N = p * q
	#Euler's totient function:
	phi = (p-1) * (q-1)

	#Generate Keys:
	while True:
		e = randint(1,phi)
		if gcd(e,phi) == 1:
			d = int(invert(e,phi))
			break

	#Generate Result:
	Pub_Key = (N,e)
	Prv_Key = (N,d)
	return Pub_Key,Prv_Key

Pub,Prv = KeyGen()

N = Pub[0]
e = Pub[1]
d = Prv[1]

#RSA Encrypt:
m = randint(1,N)
c = pow(m,e,N)

print(f'Pub_Key = {Pub}')
print(f'Prv_Key = {Prv}')
print(f'Encrypt_msg = {c}')

给了私钥直接用就好了

from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5

def MD5(m):return md5(str(m).encode()).hexdigest()


Pub_Key = (547938466798424179, 80644065229241095)
Prv_Key = (547938466798424179, 488474228706714247)
Encrypt_msg = 344136655393256706

m=pow(Encrypt_msg,Prv_Key[1],Pub_Key[0])

flag = '0xGame{'+ MD5(m) +'}'
print(flag)

Code

"""#How to use mathematics to represent information?
from Crypto.Util.number import bytes_to_long
from base64 import b64encode
from secret import flag

msg = flag.encode()
length = len(msg)

assert length%4 == 0
block = length//4
m = [ msg[ block*(i) : block*(i+1) ] for i in range(4) ]

m0 = m[0]
m1 = bytes_to_long(m[1])
m2 = m[2].hex()
m3 = b64encode(m[3])

print(f'm0 = {m0}\nm1 = {m1}\nm2 = {m2}\nm3 = {m3}')"""

照着敲就好了

from Crypto.Util.number import long_to_bytes
from base64 import b64decode
m0 = b'0xGame{73d7'
m1 = 60928972245886112747629873
m2 = "3165662d393339332d3034"
m3 = b'N2YwZTdjNGRlMX0='

print(m0+long_to_bytes(m1)+bytes.fromhex(m2)+b64decode(m3))
# b'0xGame{73d72f64-7656-11ef-9393-047f0e7c4de1}'

Code-Vigenere

from secret import flag
from os import urandom
from base64 import b64encode

def Encrypt(msg, key):
    Lenth = len(key)
    result = ''

    upper_base = ord('A')
    lower_base = ord('a')
    KEY = [ord(key.upper()[_]) - upper_base for _ in range(Lenth)]

    index = 0
    for m in msg:
        tmp_key = KEY[index%Lenth] 
        if not m.isalpha():
            result += m
            continue

        if m.isupper(): 
            result += chr(upper_base + (ord(m) - upper_base + tmp_key) % 26)
        else: 
            result += chr(lower_base + (ord(m) - lower_base + tmp_key) % 26)
        index += 1
    return result

key = b64encode(urandom(6))[:5].decode()
print(Encrypt(flag,key))

利用密文前5个字母,配合已知flag头为0xGame可以猜测出密钥

因为最后加密模了26,所以只要在26的范围内爆破一下就好了。

后面解密就把+tmp_key改成-tmp_key就好了。

c="0lCcop{oyd94092-g8mq-4963-88b6-4helrxdhm6q7}"

m="0xGame"
key=[]
upper_base = ord('A')
lower_base = ord('a')
for i in range(1,len(m)):
    for tmp_key in range(26):
        if m[i].isupper(): 
            ci = upper_base + (ord(m[i]) - upper_base + tmp_key) % 26
        else: 
            ci = lower_base + (ord(m[i]) - lower_base + tmp_key) % 26
        if ci==ord(c[i]):
            key.append(tmp_key)
            break
print(key)

index=0
flag=""
for m in c:
    tmp_key=key[index%len(key)]
    if not m.isalpha():
        flag += m
        continue

    if m.isupper(): 
        flag += chr(upper_base + (ord(m) - upper_base - tmp_key) % 26)
    else: 
        flag += chr(lower_base + (ord(m) - lower_base - tmp_key) % 26)
    index += 1
print(flag)
# 0xGame{acb94092-e8bc-4963-88f6-4fcadbbfb6c7}

Number-Theory-CRT

from Crypto.Util.number import bytes_to_long, getPrime
from hashlib import md5
from random import randint
from gmpy2 import invert,gcd

#Hash Function:
def MD5(m):return md5(str(m).encode()).hexdigest()

#RSA AlgorithmParameter Generation Function:
def KeyGen():
	Factor_BitLength = 30
	q = getPrime(Factor_BitLength)
	p = getPrime(Factor_BitLength)
	N = p * q
	#Euler's totient function:
	phi = (p-1) * (q-1)

	#Generate Keys:
	e = randint(1,phi)

	#Generate Result:
	Pub_Key = (N,e)
	return Pub_Key

Pub = KeyGen()

N = Pub[0]
e = Pub[1]

#RSA Encrypt:
m = randint(1,N)
c = pow(m,e,N)

print(f'Pub_Key = {Pub}')
print(f'Encrypt_msg = {c}')

网站分解出p,q

发现e和phi不互素,gcd为2,可以直接求出\(m^2\mod n\)

之后发现p%4=3,q%4=1

\(m^2\mod p\)使用rabin解密

然后\(m^2\mod q\)使用cipoll算法

之后枚举crt一下就好了

cipoll算法我参考的是:

https://blog.csdn.net/doyouseeman/article/details/52033204
https://unborracho.github.io/2023/04/20/二次剩余/index.html#:~:text=cipoll

from Crypto.Util.number import *
from hashlib import md5
from gmpy2 import *
from sympy.ntheory.modular import crt

def MD5(m):return md5(str(m).encode()).hexdigest()

Pub_Key = (1022053332886345327, 294200073186305890)
Encrypt_msg = 107033510346108389

# factordb
p=970868179
q=1052721013
phi=(p-1)*(q-1)
g=gcd(Pub_Key[1],phi)
gd=invert(Pub_Key[1]//g,phi)

mg=pow(Encrypt_msg,gd,Pub_Key[0])

#rabin
m1 = pow(mg, (p + 1) // 4, p)
m2 = p-pow(mg, (p + 1) // 4, p)
mp=[m1,m2]

#cipoll
def square_root_of_quadratic_residue(n, modulo):
    """Square root of quadratic residue

    Solve the square root of quadratic residue using Cipolla's algorithm with Legendre symbol
    Returns:
        int -- if n is a quadratic residue,
                   return x, such that x^{2} = n (mod modulo)
               otherwise, return -1
    """
    if modulo == 2:
        return 1
    if n % modulo == 0:
        return 0
    Legendre = lambda n: pow(n, modulo - 1 >> 1, modulo)
    if Legendre(n) == modulo - 1:
        return -1
    t = 0
    while Legendre(t ** 2 - n) != modulo - 1:
        t += 1
    w = (t ** 2 - n) % modulo
    return (generate_quadratic_field(w, modulo)(t, 1) ** (modulo + 1 >> 1)).x

def generate_quadratic_field(d, modulo=0):
    """Generate quadratic field number class

    Returns:
        class -- quadratic field number class
    """
    assert (isinstance(modulo, int) and modulo >= 0)

    class QuadraticFieldNumber:
        def __init__(self, x, y):
            self.x = x % modulo
            self.y = y % modulo

        def __mul__(self, another):
            x = self.x * another.x + d * self.y * another.y
            y = self.x * another.y + self.y * another.x
            return self.__class__(x, y)

        def __pow__(self, exponent):
            result = self.__class__(1, 0)
            if exponent:
                temporary = self.__class__(self.x, self.y)
                while exponent:
                    if exponent & 1:
                        result *= temporary
                    temporary *= temporary
                    exponent >>= 1
            return result

        def __str__(self):
            return '({}, {} \\sqrt({}))'.format(self.x, self.y, d)

    return QuadraticFieldNumber

mq=(square_root_of_quadratic_residue(mg,q))
mq=[mq,q-mq]

for i in mp:
	for j in mq:
		m=int(crt([p,q],[i,j])[0])
		flag = '0xGame{'+ MD5(m) +'}'
		print(m,flag)
#759871216848924391 0xGame{127016d0be858ef48a99723710ad4d49}

posted on 2024-10-13 21:30  Naby  阅读(71)  评论(0编辑  收藏  举报