[Week 1] Caesar Cipher
- 简单凯撒,偏移量为1
- 0xGame{The_Beginning_Of_Crypto}
[Week 1] RSA-Easy
from Crypto.Util.number import *
from hashlib import md5
def MD5(m):return md5(str(m).encode()).hexdigest()
Pub_Key = (689802261604270193, 620245111658678815)
e = Pub_Key[1]
n = Pub_Key[0]
p = 823642439
q = 837502087
c = 289281498571087475
d = inverse(e,(p-1)*(q-1))
m = pow(c,d,n)
flag = flag = '0xGame{'+ MD5(m) +'}'
print(flag)
- 0xGame{5aa4603855d01ffdc5dcf92e0e604f31}
[Week 1] Code
- 逆向,编写脚本
from Crypto.Util.number import *
from base64 import b64decode
m0 = b'0xGame{73d7'
m1 = 60928972245886112747629873
m2 = '3165662d393339332d3034'
m3 = b'N2YwZTdjNGRlMX0='
m1 = long_to_bytes(m1)
m2 = bytes.fromhex(m2)
m3 = b64decode(m3)
print(m0+m1+m2+m3)
- 0xGame{73d72f64-7656-11ef-9393-047f0e7c4de1}
[Week 1] Code-Vigenere
- 由脚本可以知道key长度为5,恰巧0xGame正好五个字母
- 编写脚本可以得到key是oWccl
alpha1 = 'abcdefghijklmnopqrstuvwxyz'
alpha2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
m = '0lCcop{oyd94092-g8mq-4963-88b6-4helrxdhm6q7}'
clue = '0xGame'
key = ''
for i in range(len(clue)):
if clue[i] in alpha1:
key += alpha1[(alpha1.find(m[i])-alpha1.find(clue[i]))%26]
elif clue[i] in alpha2:
key += alpha2[(alpha2.find(m[i])-alpha2.find(clue[i]))%26]
print(key)
- 后续可以使用工具,或者使用脚本
alpha1 = 'abcdefghijklmnopqrstuvwxyz'
alpha2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
m = '0lCcop{oyd94092-g8mq-4963-88b6-4helrxdhm6q7}'
key = 'oWccl'
key_nums = []
pointer = 0
ans = ''
for i in key:
if i in alpha1:
key_nums += [alpha1.find(i)]
elif i in alpha2:
key_nums += [alpha2.find(i)]
for i in m:
if i in alpha1:
new_index = (alpha1.find(i) - key_nums[pointer]) % 26
ans += alpha1[new_index]
pointer = (pointer + 1) % len(key_nums)
elif i in alpha2:
new_index = (alpha2.find(i) - key_nums[pointer]) % 26
ans += alpha2[new_index]
pointer = (pointer + 1) % len(key_nums)
else:
ans += i
print(ans)
- 得到0xGame{acb94092-e8bc-4963-88f6-4fcadbbfb6c7}
[Week 1] RSA-Baby
- 写脚本
from Crypto.Util.number import *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],Prv_Key[0])
flag = '0xGame{'+ MD5(m) +'}'
print(flag)
[Week 1] Number-Theory-CRT
- hint提示CRT中国剩余定理和二次剩余
二次剩余:
二次剩余(Quadratic Residue)是数论中的一个概念。简单来说,如果一个整数 𝑥的平方模 𝑛结果等于某个整数 𝑎,那么这个 𝑎就称为模 𝑛的一个二次剩余。
- 注意到
print(gmpy2.gcd(e,phi))
的输出是2,也就是说令$e’=\frac{e}{2}$有$(m^\left. e’\right. )^2\equiv c\ mod\ n$ - 要求解任意模数二次剩余先要求解奇素数模数二次剩余–具体理论查看此链
- 据此推导过程编写脚本
from Crypto.Util.number import *
from hashlib import md5
import gmpy2
import sympy
from sympy.ntheory.modular import crt
def MD5(m):return md5(str(m).encode()).hexdigest()
Pub_Key = (1022053332886345327, 294200073186305890)
c = 107033510346108389
e = Pub_Key[1]
n = Pub_Key[0]
p = 970868179
q = 1052721013
phi = (p-1) * (q-1)
print(gmpy2.gcd(e,phi)) # 发现公约数2,分析得到二次剩余
def find_quadratic_residues(a, p):
# 首先检查 a 是否是模 p 下的二次剩余
if not sympy.is_quad_residue(a, p):
return None # 如果 a 不是二次剩余,返回 None
# 使用 sympy 的 nthroot_mod 找到一个解
x = sympy.nthroot_mod(a, 2, p, all_roots=False)
# 计算另一个解
second_solution = p - x
return (x, second_solution)
x1 = find_quadratic_residues(c,p) # 求解模p下的二次剩余
x2 = find_quadratic_residues(c,q) # 求解模q下的二次剩余
for i in x1:
for j in x2:
remainders = [i,j]
mods = [p,q]
m_ = crt(mods, remainders)[0] # CRT合并得到模n的二次剩余解
c_ = m_%n
e_ = e//2
d = inverse(e_,phi)
m = pow(c_,d,n)
flag = '0xGame{'+ MD5(m) +'}'
print(flag)
- 注意的是,对于求解二次剩余有两解,所以在合并的时候都可以作为合并用的解
- 所以遍历所有组合,得到正确flag
- 0xGame{127016d0be858ef48a99723710ad4d49}