记录一下刷题&比赛中遇到的一些古典密码题
[FSCTF 2023]兔帽的奇妙冒险 附件:
1 2 有一只名叫贝斯64 先生的兔子。它戴着一顶古老的兔帽子,帽子上绣着奇异的符文,传说这是一种能与神秘力量连接的魔法帽子。 OFR3 c05 RTEFKM2 Q3 QkxqRGlTbWthWExxSXhrZFo3 SU5 DVWRkOTVFQ2 JUSE1 VcXpRQk9 hc3 hqMzRrbHRJMD0 =
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{c453 r_w4 nt_t0 _g0 _ou7 _th3 _w0 r1 d}
加密原理:
凯撒密码在线加密解密 - 千千秀字 (qqxiuzi.cn)
栅栏密码在线加密解密 - 千千秀字 (qqxiuzi.cn)
户外天堂
湘赣边武功山论剑
1 这里是修炼之人的梦想之地,风景如画、宁静安详,少侠可以联系尚宝司少卿“张程”大人,在这里稍作休息,恢复体力,继续冒险。
1 张程大人:或许维吉尼亚密码在比武中能派上用场。这种加密方法通过变换字母顺序和使用不同的密钥,能有效保护通信内容,对于保密传输至关重要,值得深入研究和应用。
1 2 kr0 gMDY1 NTY5 MDghNTU5 MsozMhU5 MzUgNiM3 NTI0 ODI5 MsA2 MrE3 CmU9 NsU1 MhcKYz01 NTkyOTk4 MDM2 Mio3 Mrg0 OTYfODE0 OTcfNjUhMiA0 MhUiODM= 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 base64def 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())
rsa 就不解释了
1 2 3 4 5 6 7 8 9 10 11 12 13 import libnumfrom xenny.ctf.crypto.modern.asymmetric.rsa import factorn=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)))
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
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, base64s = 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' )
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 stringimport libnumfrom tqdm import trangeqwer= '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