CTF 【每日一题 20160707】凯撒加密

来源:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=35

题目:凯撒加密
大概就是这样吧,不能告诉你再多了。。
U8Y]:8KdJHTXRI>XU#?!K_ecJH]kJG*bRH7YJH7YSH]=93dVZ3^S8:8"&:9U]RH;g=8Y!U92'=j*KH]ZSj&[S#!gU#*dK9.


分析:
1.基础知识
恺撒密码是一种简单的替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。
恺撒密码通常被作为其他更复杂的加密方法中的一个步骤。恺撒密码还在现代的ROT13系统中被应用。但是和所有的利用字母表进行替换的加密技术一样,恺撒密码容易被破解,在实际应用中无法保证通信安全。
凯撒是没有密匙的,即使没有密匙也能将它破解出来,因为凯撒移位密码只有25种密匙,最多就是将这25种可能性挨个检测一下可以了,这就是我们所说的暴力破解法。用软件破解或人工破解都可以。

解密推理的方法:对于有空格的凯撒移位,单字母A和I是突破口,这无异相当于告诉了移动的位数,这样很容易就被破解了。所以,如果我们要用凯撒密码的话一定要去掉空格加大破解难度。差数法:有空格时,而又没有单字母A和I时,这种方法很,如果我们令A=1,B=2,C=3……就是每个字母是字母的第几个,经过移位后的单词,每两相邻的字母之间的差值不变的。如the的差值为12,3(用前面的一个字母减前面的一个字母,当然你也可以用后面的一个字母减前面的一个字母),移动后两个相邻字母的差值也将会是12,3。对于没有空格的恺撒破解起来就比有空格的难一些,对于没有空格的我们还要对密文进行分析,找出重复出现的字母串,然后利用英文词频对字母串进行猜测。例如有3个字母串,出现的次数比较高,我们就可以试试the。
我们看到一个密码怎样判断是凯撒密码呢?这又要扯到频率分析去(在这里不介绍,在后面在说),没有经过移位的明文和移过的密文是有区别的,这样就可以区分凯撒密码和栅栏密码了
没有移位的栅栏密码元音比较多,这是语言本身的性质绝定,像英语和汉语拼音的元音出现频率就比较高。

2.这个题中比一般凯撒问题要难,因为里面含着那么多非英文字符。先不考虑题目故意绕我们的情况,就当他是个移位加密,那么出现这么多非英文字符,会不会是用ASCII码全集来进行移位加密呢?编个程序测测。

3.初步思路是,本套题的key总有一个wctf{的字符串作为开头,那么先计算这几个字符的ascii码差值,然后从上面题目字符串中逐一找出5个字符计算他们的差值,如有相符的,那么就找到了移位key了。wctf{的ascii(119 99 116 102 123)计算差值,前面字符减后面字符为(20,-17,14,-21)。下面编程序计算。

#原密文中有字符'和字符\,在python中为特殊字符,需要在前面加上\,结果不影响后续分析。
str = 'U8Y]:8KdJHTXRI>XU#?!K_ecJH]kJG*bRH7YJH7YSH]*=93dVZ3^S8*$:8"&:9U]RH;g=8Y!U92\'=j*$KH]ZSj&[S#!gU#*dK9\\.'
f = open('123.txt','w+')

def decode1():
    '''
    u'思路:试一下是否存在明文为‘wctf'的移位加密字符串。原理'wctf'字符间的差相同,移位后也相同。’
    u'实验结果:不存在这种字串,考虑可能是先经过一种编码转换,然后才按凯撒加密,所以有了decode2函数'

    '''
    for i in xrange(len(str)-1):

        if (ord(str[i]) - ord(str[i+1])== 20) or  (ord(str[i]) - ord(str[i+1])== (119-67)):
            print '1:',str[i],str[i+1]
        if ord(str[i]) - ord(str[i+1]) == -17:
            print '2:',str[i],str[i+1]

        if ord(str[i]) - ord(str[i+1]) == 14:
            destr1 = ''
            destr2 = ''
            print '3:',str[i],str[i+1]
            a = ord(str[i]) - ord('t')
            b = ord(str[i+1]) - ord('f')
            print a,b
            if a-b ==0:
                key = a         
                for j in str:
                    destr1 += chr((ord(j)-key) % 128)
                    destr2 += chr((ord(j)+key)%128)
            print >> f,'destr1:'+ destr1
            print >> f,'destr2:'+ destr2
if __name__ == '__main__':
    decode1()

经过调试和分析,我发现没那简单。这个题不是只有凯撒加密一步,还有别的处理,那会是什么呢?

4.二次尝试。一个小题,分值不高,估计也就是凯撒加密和编码转换两步。常用的编码转换是base64这类的,但base64编码后只有字母、数字、+、-、=这些字符,而密文中有很多例外,所以考虑出题人先对明文进行base64编码,然后用凯撒加密。当然这是种可能,编个函数穷举一下试试。穷举中也可以加一些取巧的判读,例如试一种凯撒解密,判断一次解密结果是不是base64编码,如果是就对它base64解码,然后匹配’wctf’。

#原密文中有字符'和字符\,在python中为特殊字符,需要在前面加上\,结果不影响后续分析。
str = 'U8Y]:8KdJHTXRI>XU#?!K_ecJH]kJG*bRH7YJH7YSH]*=93dVZ3^S8*$:8"&:9U]RH;g=8Y!U92\'=j*$KH]ZSj&[S#!gU#*dK9\\.'
f = open('123.txt','w+')
def decode2():
    '''
    思路:尝试暴力破解,之后用base64解码。
    '''
    #先穷举所有移位可能,即在移位key=1~126(ascii字符表内所有可能)
    #转换一个,base64解码一个,匹配'wctf'一次。
    pattern1 = re.compile(r'wctf',re.I)
    pattern2 = re.compile(r'^[A-Za-z0-9\+\-\=]+$')
    for key in xrange(1,127):
        d1 = ''
        for i,ch in enumerate(str):
            d1 += chr((ord(ch) + key) % 128)
        #base64码中只有字母、数字、+、 -、 =,所以非法字符就不要解码了
        if pattern2.match(d1):          
            d2 = decode_base64(d1.strip())

            if  pattern1.search(d2):
            #match方法仅匹配以模式开始的字符串,而search可以对任意位置进行匹配。
                print >> f,d2
                break

def decode_base64(data):
    #python里对base64解码时,需要对不满足长度要求的字串追加‘=’
    missing_padding = 4 - len(data) % 4
    if missing_padding < 4:
        data += b'='* missing_padding

    return base64.decodestring(data)


if __name__ == '__main__':
    decode2()

5.很幸运,上面的程序解决了问题,输出到文件123.txt中的字串为
the flag is wctf{kaisa_jiaaaaami},plz flow my weibo,http://weibo.com/woldy
那么答案是:wctf{kaisa_jiaaaaami}

文中用了点正则表达式,具体用法可参考下列文章:

  • python正则表达式基础:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
  • 正则表达式语法:http://www.runoob.com/regexp/regexp-syntax.html
    测试可以用在线的:
    http://tool.oschina.net/regex/

你可能感兴趣的:(CTF,密码技术)