破译密码crypto是我感觉很有意思的一个分支


001 base64

        下载附件打开后,是一个字符串,题目是base64, 所以直接解码得到flag。

xctf-009.jpg

002 Caesar

        下载附件后打开,也是一个字符串,题目中说是caesar密码,然后不断地循环位移就好了

def caesar(str,num):
    l = list(str)
    i = 0
    while i < len(l):
        if l[i]>='0' and l[i]<='9':
            i = i+1
        elif l[i]>='a' and l[i] <='z':
            l[i]=chr(ord('a')+(ord(l[i])+num-ord('a'))%26)
            i =i+1
        elif l[i]>='A' and l[i] <='Z':
            l[i]=chr(ord('A')+(ord(l[i])+num-ord('A'))%26)
            i=i+1
        else:
            i =i+1
    ans = "".join(l)
    return ans
def main():
    str1 = "oknqdbqmoq{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}"
    num = 26
    for i in range(num):
        caesar_str = caesar(str1,i)
        print(caesar_str)
if __name__ == "__main__":
    main()

xctf-010.jpg


003 Morse

        写一个小脚本,莫斯密码就可以不求人啦

dict1 = {'0': '.',
        '1': '-',
        ' ': '/'
        }

dict2 = {'.-': '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',
        '.----': '1',
        '..---': '2',
        '...--': '3',
        '....-': '4',
        '.....': '5',
        '-....': '6',
        '--...': '7',
        '---..': '8',
        '----.': '9',
        '-----': '0',
        '/': ' '
        }


enc_str0="11 111 010 000 0 1010 111 100 0 00 000 000 111 00 10 1 0 010 0 000 1 00 10 110"
enc_str1=""
dec_str=""
for i in enc_str0:
  enc_str1+=dict1[i]
enc_str1=enc_str1.split("/")
for i in enc_str1:
  dec_str += dict2[i]
print(dec_str)

004 Morse

        打开后发现是base64文件,用命令解密

echo -n "JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzk7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM2ODsmIzY5OyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjNTI7JiM3NjsmIzEyMjsmIzEwNzsmIzUzOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc3OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiMxMDc7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzg7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjODQ7JiM2OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzUwOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc4OyYjMTA1OyYjNTY7JiM1MzsmIzc4OyYjMTIxOyYjNTY7JiM1MzsmIzc5OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM5OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjNjk7JiMxMTk7JiM3NzsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjNjU7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM2OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjMTA3OyYjNTM7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM4NDsmIzEwNzsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzEyMDsmIzc2OyYjMTIyOyYjNjk7JiMxMjA7JiM3ODsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjMTAzOyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjMTE5Ow==" | base64 -d

得到结果

&#76;&#122;&#69;&#120;&#79;&#83;&#56;&#120;&#77;&#68;&#69;&#118;&#77;&#84;&#65;&#52;&#76;&#122;&#107;&#53;&#76;&#122;&#69;&#120;&#77;&#83;&#56;&#120;&#77;&#68;&#107;&#118;&#77;&#84;&#65;&#120;&#76;&#122;&#69;&#120;&#78;&#105;&#56;&#120;&#77;&#84;&#69;&#118;&#79;&#84;&#99;&#118;&#77;&#84;&#69;&#50;&#76;&#122;&#69;&#120;&#78;&#105;&#56;&#53;&#78;&#121;&#56;&#53;&#79;&#83;&#56;&#120;&#77;&#68;&#99;&#118;&#79;&#84;&#99;&#118;&#77;&#84;&#69;&#119;&#76;&#122;&#69;&#119;&#77;&#67;&#56;&#120;&#77;&#68;&#65;&#118;&#77;&#84;&#65;&#120;&#76;&#122;&#69;&#119;&#77;&#105;&#56;&#120;&#77;&#68;&#69;&#118;&#77;&#84;&#69;&#119;&#76;&#122;&#107;&#53;&#76;&#122;&#69;&#119;&#77;&#83;&#56;&#120;&#77;&#84;&#107;&#118;&#77;&#84;&#69;&#120;&#76;&#122;&#69;&#120;&#78;&#67;&#56;&#120;&#77;&#68;&#103;&#118;&#77;&#84;&#65;&#119;

转化为ASCII对应的字符

LzExOS8xMDEvMTA4Lzk5LzExMS8xMDkvMTAxLzExNi8xMTEvOTcvMTE2LzExNi85Ny85OS8xMDcvOTcvMTEwLzEwMC8xMDAvMTAxLzEwMi8xMDEvMTEwLzk5LzEwMS8xMTkvMTExLzExNC8xMDgvMTAw

再次base64解码

/119/101/108/99/111/109/101/116/111/97/116/116/97/99/107/97/110/100/100/101/102/101/110/99/101/119/111/114/108/100

得到welcometoattackanddefenceworld

大佬的python脚本

import base64
str1 = "JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzk7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM2ODsmIzY5OyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjNTI7JiM3NjsmIzEyMjsmIzEwNzsmIzUzOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc3OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiMxMDc7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzg7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjODQ7JiM2OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzUwOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc4OyYjMTA1OyYjNTY7JiM1MzsmIzc4OyYjMTIxOyYjNTY7JiM1MzsmIzc5OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM5OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjNjk7JiMxMTk7JiM3NzsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjNjU7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM2OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjMTA3OyYjNTM7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM4NDsmIzEwNzsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzEyMDsmIzc2OyYjMTIyOyYjNjk7JiMxMjA7JiM3ODsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjMTAzOyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjMTE5Ow=="

def dec_base64(str1):
    str = base64.b64decode(str1)
    return str
def dec_ascii(str1):
    str = ""
    str1 = str1.split(";")
    for i in str1:
        try:
            str2 = i.split("&#")[1]
            ch = chr(int(str2))
            str += ch
        except:
            pass
    return str
def dec_ascii2(str1):
    str = ""
    str1 = str1.split("/")
    for i in str1:
        try:
            ch = chr(int(i))
            str += ch
        except:
            pass
    return str

if __name__ == "__main__":
    str = dec_base64(str1)
    str = dec_ascii(str)
    str = dec_base64(str)
    str = dec_ascii2(str)

    print(str)

005 不仅仅是Morse

        将/化为空格,转化为标准morse码,进行morse解密,得到一串类似培根加密后的密文,对培根码解密即可得到flag.

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import re

# 密文转化为指定格式
s = 'AAAAABAABBBAABBAAAAAAAABAABABAAAAAAABBABAAABBAAABBAABAAAABABAABAAABBABAAABAAABAABABBAABBBABAAABABABBAAABBABAAABAABAABAAAABBABBAABBAABAABAAABAABAABAABABAABBABAAAABBABAABBA'
a = s.lower()

# 字典
CODE_TABLE = {
    'a':'aaaaa','b':'aaaab','c':'aaaba','d':'aaabb','e':'aabaa','f':'aabab','g':'aabba',
    'h':'aabbb','i':'abaaa','j':'abaab','k':'ababa','l':'ababb','m':'abbaa','n':'abbab',
    'o':'abbba','p':'abbbb','q':'baaaa','r':'baaab','s':'baaba','t':'baabb','u':'babaa',
    'v':'babab','w':'babba','x':'babbb','y':'bbaaa','z':'bbaab'
}

# 5个一组进行切割并解密
def peigendecode(peigen):
    msg =''
    codes = re.findall(r'.{5}', a)
    for code in codes:
        if code =='':
            msg += ' '
        else:
            UNCODE =dict(map(lambda t:(t[1],t[0]),CODE_TABLE.items()))
            msg += UNCODE[code]
    return msg

flag = peigendecode(a)
print('flag is ',flag)

006 幂数加密

        01248密码,又称云影密码…与二进制幂加密不同,这个加密法采用的是0作间隔,其他非0数隔开后组合起来相加表示序号1-26之一的字母(a/A,b/B,c/C…z/Z)

enc_str = "8842101220480224404014224202480122"
dec_str = ""
enc = enc_str.split("0")
for i in enc:
    sum = 0
    for k in i:
        sum +=int(k)
    ch = chr(sum + ord('A')-1)
    dec_str += ch
print(dec_str)

007 Railfence

        所谓栅栏密码,就是把要加密的明文分成N个一组,然后把每组的第1个字连起来,形成一段无规律的话。 不过栅栏密码本身有一个潜规则,就是组成栅栏的字母一般不会太多。(一般不超过30个,也就是一、两句话)

def fence(lst, numrails):
    fence = [[None] * len(lst) for n in range(numrails)]
    rails = list(range(numrails - 1)) + list(range(numrails - 1, 0, -1))
    for n, x in enumerate(lst):
        fence[rails[n % len(rails)]][n] = x
    return [c for rail in fence for c in rail if c is not None]

def encode(text, n):
    return ''.join(fence(text, n))

def decode(text, n):
    rng = range(len(text))
    pos = fence(rng, n)
    return ''.join(text[pos.index(n)] for n in rng)

z = "ccehgyaefnpeoobe{lcirg}epriec_ora_g"
for i in range(2,10):
    y = decode(z,i)
    print(y)

008 easy_RSA

安装的gmpy2,可以直接求d:

import gmpy2
p=473398607161
q=4511491
e=17
d = gmpy2.invert(e, (p-1)*(q-1))
print(d)

011 easy_ECC

1.经典密码的机械阶段——转轮机
20世纪20年代,随着机械和机电技术的成熟,以及电报和无线电需求的出现,引起了密码设备方面的一场革命——发明了转轮密码机(简称转轮机,Rotor)。转轮机由一个键盘和一系列转轮组成,每个转轮是26个字母的任意组合。转轮被齿轮连接起来,当一个转轮转动时,可以将一个字母转换成另一个字母。照此传递下去,当最后一个转轮处理完毕时,就可以得到加密后的字母。为了使转轮密码更安全,人们还把几种转轮和移动齿轮结合起来,所有转轮以不同的速度转动,并且通过调整转轮上字母的位置和速度为破译设置更大的障碍。
2.转轮机的工作原理
每一个旋转轮代表一个单表替代系统,旋转一个引脚,再转变为另一个单表替代系统。为使机器更安全,可把几种转轮和移动的齿轮结合起来。因为所有转轮以不同的速度移动,n个转轮的机器的周期是26的n次方,即n个单表替代系统。最后一个转轮转完一圈之后,它前面的转轮就旋转一个引脚,有点像时钟的齿轮。
3.恩格玛(Enigma)密码
第二次世界大战,波兰人和英国人成功破译了德国著名的的“恩格玛”密码,因此,盟军提前得知了德国的许多重大军事行动。
恩格玛密码机的工作原理
I.采用转轮机原理
II.三级替代,将第一个旋转轮的输入开关连接到另一个旋转轮。第二个旋转轮提供第二个映射。第二个映射的输入又连接到每三个旋转轮。


012 easy_ECC

# encoding=utf-8
p = 15424654874903
a = 16546484
b = 4548674875
def add(A, B):
    if A == (0, 0): return B
    if B == (0, 0): return A
    x1, y1 = A
    x2, y2 = B
    if A != B:
        r = (y2 - y1) * pow((x2 - x1), p-2, p)
    else:
        r = (x1*x1*3 + a) * pow(2*y1, p-2, p)
    x3 = r * r - x1 - x2
    y3 = r * (x1 - x3) - y1
    return (x3 % p, y3 % p)

G = (6478678675,5636379357093)
k = 546768
C = (0, 0)
for i in range(k):
    C = add(C, G)
print(C)
print("cyberpeace{%d}"%(C[0]+C[1]))
# cyberpeace{19477226185390}