密码学——实验一

密码学实验一

  • 现代密码学实验一
    • crypto -week1 program assignment
      • 题目
      • 详情与思路
      • 代码
        • 1.week1
        • PA1
        • SET1
        • 4 keyboard

现代密码学实验一

crypto -week1 program assignment

题目

  1. Coursera Dan Boneh Week 1 Program Assignment Many Time Pad

  2. PA1 option
    Write a program that allows you to “crack” ciphertexts generated using a Vigenere-like cipher, where byte-wise XOR is used instead of addition modulo 26.

  3. http://www.cryptopals.com/sets/1

    (1) Convert hex to base64
    (2) Fixed XOR
    (3) Single-byte XOR cipher
    (4) Detect single-character XOR
    (5) Implement repeating-key XOR
    (6) Break repeating-key XOR

  4. MTC3 Cracking SHA1-Hashed Passwords https://www.mysterytwisterc3.org/en/challenges/level-2/cracking-sh a1-hashed-passwords

详情与思路

题目描述(清楚描述题目中文,写出自己的理解,请勿复制原题目)

1.Coursera Dan Boneh Week 1 Program Assignment Many Time Pad
题目大意:有11个同一异或加密流密码密钥加密的密文,尝试解密最后一个密文。

思路:由于使用了同一个密钥异或加密10个明文,导致生成的密文互相异或会得到部分信息,比如空格和小写字母异或将得到大写字母,可以根据空格的位置猜测部分信息

2.PA1 option
题目大意:编写一个程序,破解使用维吉尼亚类似密码生成的密文,不过把加密方法变为了异或。
思路:由于密钥是两个4位16进制的字符串,并且加密方式位异或,可以通过遍历密钥异或密文判断有效可见明文的数量来确实密钥,得到密钥就可以破解密文。

3. http://www.cryptopals.com/sets/1
此url上的前六个问题
1)Convert hex to base64
题目大意:把16进制字符串转化为base64编码
思路:调用python函数即可转化编码

2)Fixed XOR
题目大意: 把两个等长的字符串按位进行异或
思路: 一个字符单独异或最后转化为新字符串

3)Single-byte XOR cipher
题目大意:单个字符进行异或加密。找到密钥,解密消息。
思路: 遍历密钥和密文每一位进行解密操作,破译出的可见明文越多那么越可能是密钥

4)Detect single-character XOR
题目大意: 单个字符串对txt中的一条明文进行异或加密
思路: 同第三题思路不过是要遍历整个txt

5)Implement repeating-key XOR
题目大意: 使用ICE三个字符类似维吉尼亚的分组加密字符串破译
思路: 按要求分组加密即可

6)Break repeating-key XOR
题目大意: 使用平均汉明距离破解密文,加密方法为分组异或
思路: 在不同密钥长度将密文的txt分组,取四个分组计算平均汉明距离,使用最低的几个密钥长度,按类似第三题的思路遍历找到密钥

4.MTC3CrackingSHA1-HashedPasswords
https://www.mysterytwisterc3.org/en/challenges/level-2/cracking-sh a1-hashed-passwords
以上网址的题目

题目大意:更具键盘的按键与密码输入下的限制条件和对应的sha1值判断输入的password
思路:题目给了sha1值和限制条件,遍历可能的密钥和sha1对照即可

密码学——实验一_第1张图片

代码

1.week1

import sys
from operator import methodcaller
import re


def main():
    cypherTexts = []
    # cyphertext 1 (0)
    cypherTexts.append(
        "315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e")
    # cyphertext 2 (1)
    cypherTexts.append(
        "234c02ecbbfbafa3ed18510abd11fa724fcda2018a1a8342cf064bbde548b12b07df44ba7191d9606ef4081ffde5ad46a5069d9f7f543bedb9c861bf29c7e205132eda9382b0bc2c5c4b45f919cf3a9f1cb74151f6d551f4480c82b2cb24cc5b028aa76eb7b4ab24171ab3cdadb8356f")
    # cyphertext 3 (2)
    cypherTexts.append(
        "32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb")
    # cyphertext 4 (3)
    cypherTexts.append(
        "32510ba9aab2a8a4fd06414fb517b5605cc0aa0dc91a8908c2064ba8ad5ea06a029056f47a8ad3306ef5021eafe1ac01a81197847a5c68a1b78769a37bc8f4575432c198ccb4ef63590256e305cd3a9544ee4160ead45aef520489e7da7d835402bca670bda8eb775200b8dabbba246b130f040d8ec6447e2c767f3d30ed81ea2e4c1404e1315a1010e7229be6636aaa")
    # cyphertext 5 (4)
    cypherTexts.append(
        "3f561ba9adb4b6ebec54424ba317b564418fac0dd35f8c08d31a1fe9e24fe56808c213f17c81d9607cee021dafe1e001b21ade877a5e68bea88d61b93ac5ee0d562e8e9582f5ef375f0a4ae20ed86e935de81230b59b73fb4302cd95d770c65b40aaa065f2a5e33a5a0bb5dcaba43722130f042f8ec85b7c2070")
    # cyphertext 6 (5)
    cypherTexts.append(
        "32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4")
    # cyphertext 7 (6)
    cypherTexts.append(
        "32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce")
    # cyphertext 8 (7)
    cypherTexts.append(
        "315c4eeaa8b5f8bffd11155ea506b56041c6a00c8a08854dd21a4bbde54ce56801d943ba708b8a3574f40c00fff9e00fa1439fd0654327a3bfc860b92f89ee04132ecb9298f5fd2d5e4b45e40ecc3b9d59e9417df7c95bba410e9aa2ca24c5474da2f276baa3ac325918b2daada43d6712150441c2e04f6565517f317da9d3")
    # cyphertext 9 (8)
    cypherTexts.append(
        "271946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027")
    # cyphertext 10 (9)
    cypherTexts.append(
        "466d06ece998b7a2fb1d464fed2ced7641ddaa3cc31c9941cf110abbf409ed39598005b3399ccfafb61d0315fca0a314be138a9f32503bedac8067f03adbf3575c3b8edc9ba7f537530541ab0f9f3cd04ff50d66f1d559ba520e89a2cb2a83")
    # cyphertext target (10)
    cypherTexts.append(
        "32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f904")

    # convert all to ASCII
    cypherTextsDecoded = map(methodcaller("decode", "hex"), cypherTexts)

    # chose two to XOR

    crib = "There are two types of cyptography: one that allows the Government to use brute force to break the code, and one that requires the Government to use brute force to break you"
    xorTextNum1 = 6
    xorTextNum2 = 10
    # /end interatcive

    xoredText = strxor(cypherTextsDecoded[xorTextNum1], cypherTextsDecoded[xorTextNum2])

    # loop all individual positions of the XOR-ed crypto (plain) text
    textLength = len(xoredText)
    for i in range(textLength):
        # XOR the substring with the crib
        substrXoredText = xoredText[i:]
        cribDraggedText = strxor(substrXoredText, crib)

    # do an estimated guess wether the text is readable, if so print the guess (in place)
    # if(isreadable(cribDraggedText)):
    #	printCodePos(i, cribDraggedText, textLength, '.')

    key = strxor(cypherTextsDecoded[xorTextNum1], crib)

    print "Decrypt all messages using the key:"
    for j, cypher in enumerate(cypherTextsDecoded):
        print "[%d] %s" % (j, strxor(cypher, key))


def strxor(a, b):  # xor two strings of different lengths
    if len(a) > len(b):
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
    else:
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])


def isreadable(str):  # check readability (allow only alphanumeric chars and some punctiation)
    return bool(re.search('^[a-zA-Z0-9\., \'\"\-_\:\(\)]+$', str))


def printCodePos(i, code, maxLen, filler):  # output the guess in place of the message
    prefix = filler * i
    ln = len(code)
    postfix = filler * (maxLen - i - ln)
    print("%s%s%s" % (prefix, code, postfix))


main()

PA1

# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 9:00
"""



#pa1 weijiniya like    fprintf(fpOut, "%02X", ch ^ key[i % KEY_LENGTH]); // ^ is logical XOR


def findindexkey(subarr):  # 该函数可以找出将密文subarr解密成可见字符的所有可能值
    visiable_chars = []  # 可见字符
    for x in range(32, 126):
        visiable_chars.append(chr(x))
    # print(vi)
    test_keys = []  # 用于测试密钥
    ans_keys = []  # 用于结果的返回
    for x in range(0x00, 0xFF):  # 枚举密钥里所有的值
        test_keys.append(x)
        ans_keys.append(x)
    for i in test_keys:  # 对于0x00~0xFF里的每一个数i和subarr里的每个值s异或
        for s in subarr:
            if chr(s ^ i) not in visiable_chars:  # 用i解密s,如果解密后明文不是可见字符,说明i不是密钥
                ans_keys.remove(i)  # 去掉ans_keys里测试失败的密钥
                break
    # print(ans_keys)
    return ans_keys


strmi = 'F96DE8C227A259C87EE1DA2AED57C93FE5DA36ED4EC87EF2C63AAE5B9A7EFFD673BE4ACF7BE8923C\
AB1ECE7AF2DA3DA44FCF7AE29235A24C963FF0DF3CA3599A70E5DA36BF1ECE77F8DC34BE129A6CF4D126BF\
5B9A7CFEDF3EB850D37CF0C63AA2509A76FF9227A55B9A6FE3D720A850D97AB1DD35ED5FCE6BF0D138A84C\
C931B1F121B44ECE70F6C032BD56C33FF9D320ED5CDF7AFF9226BE5BDE3FF7DD21ED56CF71F5C036A94D96\
3FF8D473A351CE3FE5DA3CB84DDB71F5C17FED51DC3FE8D732BF4D963FF3C727ED4AC87EF5DB27A451D47E\
FD9230BF47CA6BFEC12ABE4ADF72E29224A84CDF3FF5D720A459D47AF59232A35A9A7AE7D33FB85FCE7AF5\
923AA31EDB3FF7D33ABF52C33FF0D673A551D93FFCD33DA35BC831B1F43CBF1EDF67F0DF23A15B963FE5DA\
36ED68D378F4DC36BF5B9A7AFFD121B44ECE76FEDC73BE5DD27AFCD773BA5FC93FE5DA3CB859D26BB1C63C\
ED5CDF3FE2D730B84CDF3FF7DD21ED5ADF7CF0D636BE1EDB79E5D721ED57CE3FE6D320ED57D469F4DC27A8\
5A963FF3C727ED49DF3FFFDD24ED55D470E69E73AC50DE3FE5DA3ABE1EDF67F4C030A44DDF3FF5D73EA250\
C96BE3D327A84D963FE5DA32B91ED36BB1D132A31ED87AB1D021A255DF71B1C436BF479A7AF0C13AA14794'
arr = []  # 密文,每个元素为字符的ascii码
for x in range(0, len(strmi), 2):
    arr.append(int(strmi[x:2 + x], 16))

for keylen in range(1, 14):  # 枚举密钥的长度1~14
    for index in range(0, keylen):  # 对密钥里的第index个进行测试
        subarr = arr[index::keylen]  # 每隔keylen长度提取密文的内容,提取出来的内容都被密文的第index个加密
        ans_keys = findindexkey(subarr)  # 找出密钥中第index个的可能的值
        print('keylen=', keylen, 'index=', index, 'keys=', ans_keys)
        if ans_keys:  # 如果密钥第index个有可能存在,尝试用密钥的index个去解密文
            ch = []
            for x in ans_keys:
                ch.append(chr(x ^ subarr[0]))
            print(ch)
# 运行到这里,观察输出可以发现,密钥长度为7时有解
print('###############')
import string


def findindexkey2(subarr):  # 再造一个函数筛选密钥
    test_chars = string.ascii_letters + string.digits + ',' + '.' + ' '  # 将检查的字符改为英文+数字+逗号+句号+空格
    # print(test_chars)
    test_keys = []  # 用于测试密钥
    ans_keys = []  # 用于结果的返回
    for x in range(0x00, 0xFF):  # 枚举密钥里所有的值
        test_keys.append(x)
        ans_keys.append(x)
    for i in test_keys:  # 对于0x00~0xFF里的每一个数i和substr里的每个值s异或
        for s in subarr:
            if chr(s ^ i) not in test_chars:  # 用i解密s,如果解密后不是英文、数字、逗号、句号、空格,说明i不是密钥
                ans_keys.remove(i)  # 去掉ans_keys里测试失败的密钥
                break
    # print(ans_keys)
    return ans_keys


vigenerekeys = []  # 维基尼尔密码的密钥
for index in range(0, 7):  # 已经知道密钥长度是7
    subarr = arr[index::7]
    vigenerekeys.append(findindexkey2(subarr))
print(vigenerekeys)  # 输出的是[[186], [31], [145], [178], [83], [205], [62]].

print("#########")
ming = ''
for i in range(0, len(arr)):
    ming = ming + chr(arr[i] ^ vigenerekeys[i % 7][0])
print(ming)



SET1

1

# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 9:01
"""

import base64

def hex_to_base64(hexString):
    return base64.b64encode(hexString.decode('hex'))

string="49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"
print (hex_to_base64(string))

2

# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 9:08
"""

import string
import re

def xor_strings(xs,ys):
    return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys))

if __name__ == '__main__':
    string1='1c0111001f010100061a024b53535009181c'
    string2='686974207468652062756c6c277320657965'
    hex_string1=string1.encode('utf-8').decode('hex')  #转化为utf-8 异或
    hex_string2=string2.encode('utf-8').decode('hex')
    result=xor_strings(hex_string1,hex_string2).encode('hex') #hex输出
    print (result)

3

#coding=utf-8
import re
str="1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"
score=0#max
for i in range(0,129):
    tmp=[]
    for j in re.findall(".{2}",str):#任意两个字符的字符串
        tmp += chr(i^int(j,16))
    tmpstr = "".join(tmp)
    num=0
    for j in range(0,len(tmpstr)):
        if tmpstr[j]>='a'and tmpstr[j]<='z':#or tmpstr[j]>='A'and tmpstr[j]<='Z':
            num+=1
    if num>score:
        #print tmpstr
        score=num#用于更新用
        ansstr=tmpstr
        key=chr(i)
print key
print ansstr

4

#coding=utf-8
import re
#with open("ex4.txt") as fp:
#wenben=[i for i in open("ex4.txt").readlines()]
wenben=[]
for i in open("4.txt","r").readlines():
    wenben+=[i.replace("\n","")] #序列相加  #同第三题
score=0
for k in wenben:
    for i in range(0,129):
        tmp=[]
        for j in re.findall(".{2}",k):#任意两个字符的字符串
            tmp += chr(i^int(j,16))
        tmpstr = "".join(tmp)
        num=0
        num=len(re.findall(r'[a-zA-Z ]',tmpstr))#一定注意不要落下空格
        if num>score:
            score=num#用于更新用
            ansstr=tmpstr
            c=k
            key=chr(i)
print c
print key
print ansstr

5

# -*- coding: utf-8 -*-

def xor_repeat_key(key,string):
	key_len=len(key)
	result=''
	str_result=''
	for index,ch in enumerate(string):
		n=index%key_len#一组组加密
		b=chr(ord(key[n])^ord(ch))
		str_result+=b
	return str_result


def main():
	string1='Burning \'em, if you ain\'t quick and nimble\nI go crazy when I hear a cymbal'
	key='ICE'
	print xor_repeat_key(key,string1).encode('hex')


if __name__ == '__main__':
	main()

6

#coding:utf-8
import re
import base64
with open("6.txt","r") as fp:
    wenben=[base64.b64decode(i) for i in fp.readlines()]
wenben="".join(wenben)

def english_test(sentence):#字母频率
    score = 0
    freqs = {
        'a': 0.0651738, 'b': 0.0124248, 'c': 0.0217339,
        'd': 0.0349835, 'e': 0.1041442, 'f': 0.0197881,
        'g': 0.0158610, 'h': 0.0492888, 'i': 0.0558094,
        'j': 0.0009033, 'k': 0.0050529, 'l': 0.0331490,
        'm': 0.0202124, 'n': 0.0564513, 'o': 0.0596302,
        'p': 0.0137645, 'q': 0.0008606, 'r': 0.0497563,
        's': 0.0515760, 't': 0.0729357, 'u': 0.0225134,
        'v': 0.0082903, 'w': 0.0171272, 'x': 0.0013692,
        'y': 0.0145984, 'z': 0.0007836, ' ': 0.1918182}
    for x in sentence.lower():
        if x in freqs:
            score += freqs[x]
    return score

def hanming(x,y):
    num=0
    for i in range(0,len(x)):
        t=ord(x[i])^ord(y[i])
        while t:
           if t&1 : num+=1
           t>>=1
    return num

def thechar(st1):
    score = 0
    for i in range(0, 255):
        tmp = []
        for j in range(0,len(st1)):  # 任意两个字符的字符串
            tmp += chr(i ^ int(st1[j],16))
        tmpstr = "".join(tmp)

        #num=len(re.findall(r'[a-zA-Z ,\.;?!:]',tmpstr))  #'[a-zA-Z ,\.?!:;]'
        num=english_test(tmpstr)
        if num > score:
            score = num  # 用于更新用
            key = chr(i)
            #print key,score
    return key


ans = []
for i in range(1,41):
    str1=[]
    str2=[]
    str3=[]
    str4=[]
    for j in range(0,i): str1+=[wenben[j]]
    for j in range(i,2*i): str2+=[wenben[j]]
    for j in range(2*i,3*i): str3+=[wenben[j]]
    for j in range(3*i,4*i): str4+=[wenben[j]]
    str1="".join(str1)
    str2="".join(str2)
    str3="".join(str3)
    str4="".join(str4)
    x1=float(hanming(str1,str2))/i
    x2=float(hanming(str2,str3))/i
    x3=float(hanming(str3,str4))/i
    x4=float(hanming(str1,str4))/i
    x5=float(hanming(str1,str3))/i
    x6=float(hanming(str2,str4))/i
    aa=(x1+x2+x3+x4+x5+x6)/6
    ans+=[(i,aa)]
ans.sort(lambda x,y:cmp(x[1],y[1]))
#print "hello\n"
for i in range(len(ans)):
    print ans[i][0],ans[i][1]
#print len(wenben)
#print len(wenben)%29
wenben=wenben.encode('hex')

block=[re.findall(r'(.{2})',z)  for z in re.findall(r'(.{58})',wenben)]#29



keyy = []
for i in range(0,29):
    tmp=[]
    for j in range(0,len(block)):
        tmp+=[block[j][i]]
    keyy+=[thechar(tmp)]
keyy="".join(keyy)

print "hello\n"
print keyy
print "hello\n"
keyy=keyy*10000

wenben=wenben.decode('hex')
an=[]
for i in range(0,len(wenben)):
    an+=[chr(ord(wenben[i])^ord(keyy[i]))]
an="".join(an)
print an

4 keyboard

# _*_ coding:utf-8 _*_
"""
@author km
@time: 2019/10/18 11:34
"""
#暴力破解
import re
from Crypto.Hash import SHA
import hashlib
import itertools
import datetime
starttime = datetime.datetime.now()
hash1="67ae1a64661ac8b4494666f58c4822408dd0a3e4"
str1="QqWw%58(=0Ii*+nN"
str2=[['Q', 'q'],[ 'W', 'w'],[ '%', '5'], ['8', '('],[ '=', '0'], ['I', 'i'], ['*', '+'], ['n', 'N']]
def sha_encrypt(str):
    sha = hashlib.sha1(str)
    encrypts = sha.hexdigest()
    return encrypts
st3="0"*8
str4=""
str3=list(st3)
for a in range(0,2):
    str3[0]=str2[0][a]
    for b in range(0,2):
        str3[1]=str2[1][b]
        for c in range(0,2):
            str3[2]=str2[2][c]
            for d in range(0,2):
               str3[3] = str2[3][d]
               for e in range(0,2):
                   str3[4] = str2[4][e]
                   for f in range(0,2):
                       str3[5] = str2[5][f]
                       for g in range(0,2):
                           str3[6] = str2[6][g]
                           for h in range(0,2):
                               str3[7] = str2[7][h]
                               newS="".join(str3)
                               for i in itertools.permutations(newS, 8):
                                   str4 = sha_encrypt("".join(i))
                                   if str4==hash1:
                                       print "".join(i)
                                       endtime = datetime.datetime.now()
                                       print (endtime - starttime).seconds
                                       exit(0)

你可能感兴趣的:(密码学)