• Home
  • About
    • Rhy7hm photo

      Rhy7hm

      天天被计算机教做人

    • Learn More
    • Email
  • Posts
    • All Posts
    • All Tags
  • Projects

ctfwiki_Crypto_overview之cryptopals

12 Sep 2018

Reading time ~1 minute


我发现

https://cryptopals.com/

好好玩……

(虽然不太会玩

于是不务正业地秒了前三题

1.Convert hex to base64

from base64 import *
def hex2b64(s):
    return b64encode(s.decode('hex'))

2.Fixed XOR

def xor(a,b):
    return ''.join(chr(ord(x)^ord(y)) for x,y in zip(a,b))

3.Single-byte XOR cipher

这题第一反应是写循环遍历所有可能性,print出结果都为可见字符的然后肉眼看……

def single_byte_xor_loop(s):
    for i in range(0,256):
        rs = ''.join(chr(ord(x)^i) for x in s)
        if max(rs) <= '~' and min(rs) >=' ':
            print rs

结果:

\pptvqx?R\8l?svtz?~?opjq{?py?}~|pq
Q}}y{|u2_Q5a2~{yw2s2b}g|v2}t2psq}|
Vzz~|{r5XV2f5y|~p5t5ez`{q5zs5wtvz{
Txx|~yp7ZT0d7{~|r7v7gxbys7xq7uvtxy
Kggcafo(EK/{(dacm(i(xg}fl(gn(jikgf
Jffb`gn)DJ.z)e`bl)h)yf|gm)fo)khjfg
Hdd`bel+FH,x+gb`n+j+{d~eo+dm+ijhde
Nbbfdcj-@N*~-adfh-l-}bxci-bk-olnbc
Maaeg`i.CM)}.bgek.o.~a{`j.ah.loma`
Cooking MC's like a pound of bacon
Bnnjhof!LB&r!mhjd!`!qntoe!ng!c`bno
Ammikle"OA%q"nkig"c"rmwlf"md"`caml
@llhjmd#N@$p#ojhf#b#slvmg#le#ab`lm
Gkkomjc$IG#w$hmoa$e$tkqj`$kb$fegkj
Fjjnlkb%HF"v%iln`%d%ujpka%jc%gdfjk
Eiimoha&KE!u&jomc&g&vishb&i`&dgeih
Dhhlni`'JD t'knlb'f'whric'ha'efdhi

显然明文为Cooking MC's like a pound of bacon

但是题目要求设置一个对明文的评分,这点让我有点脑壳疼

首先我的第一反应是,根据英文的字符频率,e是频率最大的,所以可以断定密文字符串中出现频率最大的字符和e异或就是key,但是一看明文e只出现了一次就……gg了

//啊这里主要是忽视了还用空格的存在……维基百科上毕竟还有一句英语中空格出现的频率比使用最多的字母(e)还稍稍多点[9](约为107%)

如果是按照这个思路可以这么写:

def single_byte_xor_single_frenquency(s):
    t = s[0]
    for i in s:
        t = i if s.count(t) < s.count(i) else t
    key = ord(t)^ord(' ')
    return ''.join(chr(ord(x)^key) for x in s)

注:参数要先.decode(‘hex’) 注2:使用三元运算符的时候别漏了else

当然正确答案不能这么简单的……正确答案它……是要评分的……

参考:

https://laconicwolf.com/2018/05/29/cryptopals-challenge-3-single-byte-xor-cipher-in-python/

↑这个在字母频率表里加了空格

↑评分方法是: sum([character_frequencies.get(chr(byte), 0) for byte in input_bytes.lower()])

即遍历字符串,把每个字符*该字符在英语中的频率求和


彩蛋:

python3中,bytes.fromhex(hexstring)使一个十六进制格式的字符串转化为一个整数不可变序列

如:

hexstring = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736'
>>> ciphertext = bytes.fromhex(hexstring)
>>> ciphertext
b'\x1b77316?x\x15\x1b\x7f+x413=x9x(7-6<x7>x:9;76'
>>> ciphertext[0]
27
>>> ciphertext[1]
55
>>> 0x1b
27

彩蛋: 按字典中的某个关键字排序:

sorted(potential_messages, key=lambda x: x['score'])


https://github.com/Lukasa/cryptopals/blob/master/cryptopals/challenge_one/three.py

↑这篇用的评分方法是:

math.sqrt(FREQUENCY_TABLE.get(char, 0) * y/total_characters) for char, y in c.items()

彩蛋:计数统计

>> from collections import Counter
>>> a
{'b': 6}
>>> a = [111,2,333,111]
>>> Counter(a)
Counter({111: 2, 2: 1, 333: 1})

继续ctfwiki

基于秘钥的凯撒密码:

如 XMan 一期夏令营分享赛宫保鸡丁队 Crypto 100

密文:s0a6u3u1s0bv1a
密钥:guangtou
偏移:6,20,0,13,6,19,14,20
明文:y0u6u3h1y0uj1u

Atbash Cipher

明文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
密文:Z Y X W V U T S R Q P O N M L K J I H G F E D C B A

solve:http://www.practicalcryptography.com/ciphers/classical-era/atbash-cipher/


仿射密码:

(完了我好像在回忆童年那样(不是

E(x) = ax + b mod m,a和m互素 D(x) = a的逆元(x-b) mod m

若知道两个明密文对即可利用两式相减解出a和b

彩蛋:'%02x' % c表示以十六进制形式输出02 表示不足两位,前面补0输出



ctfwikiCryptocryptopals Share Tweet +1