0%

古典杂记

记录一下刷题&比赛中遇到的一些古典密码题

[FSCTF 2023]兔帽的奇妙冒险

附件:

1
2
有一只名叫贝斯64先生的兔子。它戴着一顶古老的兔帽子,帽子上绣着奇异的符文,传说这是一种能与神秘力量连接的魔法帽子。
OFR3c05RTEFKM2Q3QkxqRGlTbWthWExxSXhrZFo3SU5DVWRkOTVFQ2JUSE1VcXpRQk9hc3hqMzRrbHRJMD0=

base64 解密一下

8TwsNQLAJ3d7BLjDiSmkaXLqIxkdZ7INCUdd95ECbTHMUqzQBOasxj34kltI0=

再加上 Rabbit 特征的密文头 U2FsdGVkX1 再Rabbit 解密

FSCTF{Bunny_is_so_cute_Why_e@t_bunny}

[MoeCTF 2021]OldButPopular

附件

1
2
qj3r_y31s{vxk7_hig__0_a}g4ax_x0x540slv
你能解密出这段是什么意思吗? 观察一下这段密文格式有什么不一样

一看就是移了顺序的,而且 {} 也移了,栅栏密码:所有字母变换位置但字母不变

这题的flag头 不是 flag就是 moectf,密文里没有,那就是字母变换了,大概是凯撒加密了

因为凯撒只对26个字母加密,所以{}是不动的,所以我们可以先进行凯撒解密通过 {} 来筛选正确的密文

1
qsigxj{g453v_a4rx_x0_k0_sy7_xl3_a0v1h}

在线网址枚举或者随波逐流一把梭

1
moectf{c453r_w4nt_t0_g0_ou7_th3_w0r1d}

加密原理:

凯撒密码在线加密解密 - 千千秀字 (qqxiuzi.cn)

栅栏密码在线加密解密 - 千千秀字 (qqxiuzi.cn)

户外天堂

湘赣边武功山论剑

1
这里是修炼之人的梦想之地,风景如画、宁静安详,少侠可以联系尚宝司少卿“张程”大人,在这里稍作休息,恢复体力,继续冒险。
1
张程大人:或许维吉尼亚密码在比武中能派上用场。这种加密方法通过变换字母顺序和使用不同的密钥,能有效保护通信内容,对于保密传输至关重要,值得深入研究和应用。
1
2
kr0gMDY1NTY5MDghNTU5MsozMhU5MzUgNiM3NTI0ODI5MsA2MrE3CmU9NsU1MhcKYz01NTkyOTk4MDM2Mio3Mrg0OTYfODE0OTcfNjUhMiA0MhUiODM=
key:rsa

小改了一下字典,加密字典变成了小写字母,除小写外其他字符不变

因为字典的不同,所以在线网站工具都解不对,只能自己敲代码

所以我们需要理解原理来进行编写

1,$len(key) \le len(message)$ ,当密钥的长度小于明文长度时,需要重复拼接key到相同长度

2,

注:模数 26 是 字典的长度,即 p = len(table) ,字典长度为几,模数为几

Mi 就是 M这个明文在字母表中的索引值,比如表是 abcdefghijklmnopqrstuvwxyz, 假如 M 为 b, 那 Mi 就表示 1 (表是a-z,下标也就是0-25)

同样,Ki 就是 Mi 所对应的 K的索引值,假设明文 M 对应的是密钥 r,在表中的索引值就是 17,于是 Ki=17

具体可以结合下面的exp进行理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import base64

def pad_key(key, length):
Key = key * length
return Key[:length]

def encrypt(message, table, key):
enc = ''
Key = pad_key(key, length)
for i in range(length):
if message[i].islower():
enc += table[(table.index(message[i]) + table.index(Key[i])) % len(table)]
else:
enc += message[i]
return enc

message = 'kr0gMDY1NTY5MDghNTU5MsozMhU5MzUgNiM3NTI0ODI5MsA2MrE3CmU9NsU1MhcKYz01NTkyOTk4MDM2Mio3Mrg0OTYfODE0OTcfNjUhMiA0MhUiODM='
table = 'abcdefghijklmnopqrstuvwxyz'
key = 'rsa'
length = len(message)

print(base64.b64decode(encrypt(message,table,key)).decode())

# n=1065569082559283359352737524829206217
# e=65537
# c=557299803638728496181497065330435383

rsa 就不解释了

1
2
3
4
5
6
7
8
9
10
11
12
13
import libnum
from xenny.ctf.crypto.modern.asymmetric.rsa import factor

n=1065569082559283359352737524829206217
e=65537
c=557299803638728496181497065330435383

p,q = factor.attack(n)
d=libnum.invmod(e,(p-1)*(q-1))
m = pow(c,d,n)
print(libnum.n2s(pow(c,d,n)))

# flag{DraG0o0n}

easy_crypto

2024-09-05

1
2
3
4
key.txt
1091091153210977773210977109457732774646324677831153277464546324611511545838377321098377

flag.rar

题目内容:谐音一点都不好玩,但好在差别不大。

尝试了很多,最后可能是拼凑的ascii码,

1
2
3
4
5
6
7
8
9
10
str = '1091091153210977773210977109457732774646324677831153277464546324611511545838377'

num = 0
while num <= len(str):
for j in range(2, 4):
if 32 <= int(str[num:num + j]) <= 126:
print(chr(int(str[num:num + j])), end='')
num += j

# mms mMM mMm-M M.. .MSs M.-. .ss-SSM$

ms,摩斯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
str = 'mms mMM mMm-M M.. .MSs M.-. .ss-SSM mSM'
M = ['M', 'm', '.']
S = ['S', 's', '.']
for i in str:
if i in M:
print('.', end='')
elif i == ' ':
print('/', end='')
else:
print('-', end='')

print()

for i in str:
if i in S:
print('.', end='')
elif i == ' ':
print('/', end='')
else:
print('-', end='')


# ..-/.../...-./.../..--/..-./.-----./.-.

# --./---/-----/-../.-../-.-./...-..-/-.-

得到key:GO0DLC$K

打开flag压缩包是一大堆base

由结果可知进行了50次base64加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import re, base64
s = open('flag.txt', 'rb').read()
base16_dic = r'^[A-F0-9=]*$'
base32_dic = r'^[A-Z2-7=]*$'
base64_dic = r'^[A-Za-z0-9/+=]*$'
n= 0
while True:
n += 1
t = s.decode()
if '{' in t:
print(t)
break
elif re.match(base16_dic, t):
s = base64.b16decode(s)
print(str(n) + ' base16')
elif re.match(base32_dic, t):
s = base64.b32decode(s)
print(str(n) + ' base32')
elif re.match(base64_dic, t):
s = base64.b64decode(s)
print(str(n) + ' base64')

# DASCTF{a3dcb4d229de6fde0db5686dee47145d}

Affine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import string
import libnum
from tqdm import trange

qwer= 'flag{' # flag{
sercet='aipx{823j56p37ap92p93pd4g7ad6a0p01p21}'
dic = string.ascii_lowercase

def affine_decrypt(ciphertext, a, b, dic):
m = len(dic)
a_inv = libnum.invmod(a, m)
plaintext = ''

for char in ciphertext:
if char in dic:
y = dic.index(char)
x = (a_inv * (y - b)) % m
plaintext += dic[x]
else:
plaintext += char
return plaintext

n = 26
for a in trange(100):
for b in range(100):
c=''
for j in qwer:
if ord(j) >= ord("a") and ord(j) <= ord("z"):
cha=ord(j)-ord('a')
c+=chr((a * cha+ b) % n+ord('a'))
else:
c+=j

if 'aipx' in c:
print(c)
print(a,b)
print((affine_decrypt(sercet,a,b,dic)))
break
-------------    本文结束  感谢阅读    -------------