【信息安全】seed-labs实验-Secret-Key Encryption Lab

Task 1: Frequency Analysis

大致原理:单表替换密码(将明文中的字母按照对照表映射成密文),会将明文中的统计规律带到密文中,如明文中出现最多的是A,则密文中出现最多的就是A在对照表下的密文。因此我们可以通过频率分析的方法找到对照表,破解密文。
代码思想:读入密文ciphertext.txt(只有小写的字母+空格+回车的密文),然后统计其中各个字母出现的次数并对统计结果进行排序。然后我们还有一个已知的排序结果words_frequency(这个是百度搜到的公开单字母频率),这两个排序结果的对应关系我们就认为是对照表了,接着使用这个对照表翻译密文得到明文out.txt

vim task1.py
sudo python3 task1.py

def get_frequency(path):
    res = {}
    for i in range(ord('a'),ord('z')+1):
        res[chr(i)]=0
    with open(path) as f:
        for line in f.readlines():
            for ch in line.strip():
                if ch.isalpha():
                    res[ch.lower()] +=1
    
    return sorted(res.items(),key=lambda s:s[1],reverse=True)

def main():
    ciphertext_frequency= get_frequency('./ciphertext.txt')
    words_frequency= "ETAOINRSHDCLMPUFGWYBKJVXQZ";
    trans = {}
    for i in range(26):
        trans[ciphertext_frequency[i][0]] = words_frequency[i].lower()
    with open('./out.txt',mode='a') as f1:
        with open('./ciphertext.txt') as f2:
            for line in f2.readlines():
                for ch in line.strip():
                    if ch.isalpha():
                        f1.write(trans[ch.lower()])
                    else:
                        f1.write(ch)


if __name__ == '__main__':
    main()

Task 2: Encryption using Different Ciphers and Modes

用AES加密算法(128位密钥,CBC模式)加密一个文件并进行解密。

openssl enc -aes-128-cbc -e -in ./plaintext.txt -out cipher.bin -K 00112233445566778889aabbccddeeff -iv 0102030405060708

openssl enc -aes-128-cbc -d -in cipher.bin -out out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708

用AES加密算法(128位密钥),分别采用ECB和CBC模式加密一个bmp图片,查看加密后的图片。

openssl enc -aes-128-ecb -in ./pic_original.bmp -out ./pic_ecb.bmp -e -K 00112233445566778889aabbccddeeff 

openssl enc -aes-128-cbc -in ./pic_original.bmp -out ./pic_cbc.bmp -e -K 00112233445566778889aabbccddeeff -iv 0102030405060708

在这里插入图片描述
发现图片无法查看,因为.bmp文件的前54个字节包含图片的标题信息,被我们加密了,我们重新调整一下,下面获取原图片的标题信息(前54字节),结合新图片的内容信息(55以后字节),构造新的图片

head -c 54 ./pic_original.bmp >header
tail -c +55 pic_ecb.bmp > ecb_body
tail -c +55 pic_cbc.bmp > cbc_body
cat header ecb_body > newECB.bmp
cat header cbc_body > newCBC.bmp

在这里插入图片描述
在这里插入图片描述
我们可以发现,CBC模式的加密比较彻底,而ECB模式的加密仍然会显示出原文的统计信息。

Task 4: Padding

分别创建大小为5,10,15字节的文件

echo -n "01234" > 5.txt
echo -n "0123456789" > 10.txt
echo -n "012345678999999" > 15.txt

在这里插入图片描述

先用AES加密算法(128位密钥,CBC模式)加密这些文件,然后解密这些密文(选择解密时不去除padding的选项),观察解密后各个文件的尺寸大小

注:我们在解密的时候添加了参数-nopad,表示不去除padding

openssl enc -aes-128-cbc -e -in ./5.txt -out ./cbc/5-cbc.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
openssl enc -aes-128-cbc -e -in ./10.txt -out ./cbc/10-cbc.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
openssl enc -aes-128-cbc -e -in ./15.txt -out ./cbc/15-cbc.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708

openssl enc -aes-128-cbc -d -in ./cbc/5-cbc.txt -out ./cbc/5-cbc-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
openssl enc -aes-128-cbc -d -in ./cbc/10-cbc.txt -out ./cbc/10-cbc-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
openssl enc -aes-128-cbc -d -in ./cbc/15-cbc.txt -out ./cbc/15-cbc-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad

在这里插入图片描述

用xxd命令查看各个解密文件中padding的内容

xxd 5-cbc-out.txt
xxd 10-cbc-out.txt
xxd 15-cbc-out.txt

在这里插入图片描述

用AES加密算法(128位密钥,ECB模式,CFB模式,OFB模式)进行类似上述(2)和(3)的操作,查看各个解密文件中padding的内容。

注:观察发现,ECB、CBC出现填充,而CFB、OFB没有填充。因为CFB、OFB可以将DES转换为流密码。

ecb
openssl enc -aes-128-ecb -e -in ./5.txt -out ./ecb/5-ecb.txt -K 00112233445566778889aabbccddeeff 
openssl enc -aes-128-ecb -e -in ./10.txt -out ./ecb/10-ecb.txt -K 00112233445566778889aabbccddeeff
openssl enc -aes-128-ecb -e -in ./15.txt -out ./ecb/15-ecb.txt -K 00112233445566778889aabbccddeeff 

openssl enc -aes-128-ecb -d -in ./ecb/5-ecb.txt -out ./ecb/5-ecb-out.txt -K 00112233445566778889aabbccddeeff -nopad
openssl enc -aes-128-ecb -d -in ./ecb/10-ecb.txt -out ./ecb/10-ecb-out.txt -K 00112233445566778889aabbccddeeff -nopad
openssl enc -aes-128-ecb -d -in ./ecb/15-ecb.txt -out ./ecb/15-ecb-out.txt -K 00112233445566778889aabbccddeeff -nopad

xxd 5-ecb-out.txt
xxd 10-ecb-out.txt
xxd 15-ecb-out.txt

在这里插入图片描述
注:xxd的第三列表示的是这一行原本的内容,发现多了一些...
在这里插入图片描述


cfb
openssl enc -aes-128-cfb -e -in ./5.txt -out ./cfb/5-cfb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
openssl enc -aes-128-cfb -e -in ./10.txt -out ./cfb/10-cfb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
openssl enc -aes-128-cfb -e -in ./15.txt -out ./cfb/15-cfb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708

openssl enc -aes-128-cfb -d -in ./cfb/5-cfb.txt -out ./cfb/5-cfb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
openssl enc -aes-128-cfb -d -in ./cfb/10-cfb.txt -out ./cfb/10-cfb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
openssl enc -aes-128-cfb -d -in ./cfb/15-cfb.txt -out ./cfb/15-cfb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad

xxd 5-cfb-out.txt
xxd 10-cfb-out.txt
xxd 15-cfb-out.txt

在这里插入图片描述
在这里插入图片描述

ofb
openssl enc -aes-128-ofb -e -in ./5.txt -out ./ofb/5-ofb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
openssl enc -aes-128-ofb -e -in ./10.txt -out ./ofb/10-ofb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
openssl enc -aes-128-ofb -e -in ./15.txt -out ./ofb/15-ofb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708

openssl enc -aes-128-ofb -d -in ./ofb/5-ofb.txt -out ./ofb/5-ofb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
openssl enc -aes-128-ofb -d -in ./ofb/10-ofb.txt -out ./ofb/10-ofb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
openssl enc -aes-128-ofb -d -in ./ofb/15-ofb.txt -out ./ofb/15-ofb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708 -nopad
 
xxd 5-ofb-out.txt
xxd 10-ofb-out.txt
xxd 15-ofb-out.txt

在这里插入图片描述
在这里插入图片描述

Task 5: Error Propagation – Corrupted Cipher Text

创建一个至少1000字节大的文本文件

#!/bin/bash

f=""
for (( i = 1; i < 1024; ++i)); do f=$f"6"; done
echo $f >> f.txt

用AES加密算法(128位密钥,ECB模式)加密这个文件

openssl enc -aes-128-ecb -e -in ./f.txt -out ./ecb/f-ecb.txt -K 00112233445566778889aabbccddeeff 

用bless工具修改密文中第55个字节中的1个bit

bless ./ecb/f-ecb.txt

注:bless工具貌似是不支持直接修改的,只能删除、复制和黏贴。比如我想将DF修改成EF,做法就是选中EF(是鼠标拖动,让ED块变红),然后右键复制,选中DF右键删除,然后再右键黏贴。
在这里插入图片描述
在这里插入图片描述

解密被上述修改后的密文,查看解密后的明文有什么变化

openssl enc -aes-128-ecb -d -in ./ecb、f-ecb.txt -out ./ecb/f-ecb-out.txt -K 00112233445566778889aabbccddeeff 
xxd ./ecb/f-ecb-out.txt

在这里插入图片描述

用AES加密算法(128位密钥,CBC模式,OFB模式)进行类似上述(2)-(4)的操作,查看对应解密后的明文有什么变化
注:不同的模式下,密文改变带来的影响不同,具体怎么个不同法和采用的模式有关。

cbc模式
openssl enc -aes-128-cbc -e -in ./f.txt -out ./cbc/f-cbc.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
bless ./cbc/f-cbc.txt
openssl enc -aes-128-cbc -d -in ./cbc/f-cbc.txt -out ./cbc/f-cbc-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
xxd ./cbc/f-cbc-out.txt

ofb模式
openssl enc -aes-128-ofb -e -in ./f.txt -out ./ofb/f-ofb.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
bless ./ofb/f-ofb.txt
openssl enc -aes-128-ofb -d -in ./ofb/f-ofb.txt -out ./ofb/f-ofb-out.txt -K 00112233445566778889aabbccddeeff -iv 0102030405060708
xxd ./ofb/f-ofb-out.txt

在这里插入图片描述
在这里插入图片描述
注:只有OFB模式不存在扩散问题,一个字节错误不会影响整组的解密错误,仅第55字节错误

Task 6: Initial Vector (IV) and Common Mistakes

Task 6.1. IV Experiment

用AES加密算法(128位密钥,CBC模式),采用相同的密钥和不同的初始化向量加密一个相同的文件,观察加密结果是否相同

echo -n "01234" > f.txt
openssl enc -aes-128-cbc -e -in ./f.txt -out ./f-cbc-iv1.txt -K 123456 -iv 111111
openssl enc -aes-128-cbc -e -in ./f.txt -out ./f-cbc-iv2.txt -K 123456 -iv 222222
cat f-cbc-iv1.txt
cat f-cbc-iv2.txt

在这里插入图片描述

用AES加密算法(128位密钥,CBC模式),采用相同的密钥和相同的初始化向量加密一个相同的文件,观察加密结果是否相同

openssl enc -aes-128-cbc -e -in ./f.txt -out ./f-cbc-iv1-same.txt -K 123456 -iv 111111
cat f-cbc-iv1.txt
cat f-cbc-iv1-same.txt

在这里插入图片描述

思考为什么IV必须唯一
从实验结果可以发现,在key相同的情况,相同的IV会导致加密结果相同,所以为了信息安全IV必须唯一。

Task 6.2. Common Mistake: Use the Same IV

已知明文攻击:假设采用OFB模式进行加密,加密时所采用的IV是相同的,请破译P2的内容。
在这里插入图片描述
在这里插入图片描述

Task 6.3. Common Mistake: Use a Predictable IV

首先使用提供的命令创建容器,然后操作
课堂上大佬说,将Yes和No的16字节形式输入进去,然后对比一下就出结果了,我实在是看不出来啊

下面分别是Yes和No的16字节形式
5965730D0D0D0D0D0D0D0D0D0D0D0D0D
4E6F0E0E0E0E0E0E0E0E0E0E0E0E0E0E

在这里插入图片描述

Task 7: Programming using the Crypto Library

大致思想:这个任务说的是,已知key是由words.txt文件中的某一行填充而成,给你明文、密文、iv以及words.txt,能不能找到key
代码思路:核心思想就是把words.txt中的每一个单词当成key,结合已知的iv构造aes,然后使用这个aes去解码密文,如果得到的明文和已知明文相同,那就找到了key。
碰到的问题:python中的Crypto包,把iv定死了成16bite,而任务给的是32bite的iv,没有办法,就自己重新生成了密文,希望老师不介意。(并且自己来做的话,填充函数这边就可以自己发挥了)

import base64
from Crypto.Cipher import AES

class EncryptDate:
    def __init__(self, key, iv):
        self.length = 16  
        self.key = self.pad(key).encode("utf-8")                          
        self.iv = iv.encode("utf-8")                            
                                              
        self.aes = AES.new(self.key, AES.MODE_CBC, self.iv)     
        self.unpad = lambda s: s[0:-s[-1]]

    def pad(self, text): # 填充函数
        count = len(text.encode('utf-8'))
        add = self.length - (count % self.length)
        entext = text + (chr(add) * add)
        return entext

    def encrypt(self, encrData):  # 加密函数
        a = self.pad(encrData)
        res = self.aes.encrypt(a.encode("utf-8"))
        msg = str(base64.b64encode(res), encoding="utf8")
        return msg

    def decrypt(self, decrData):  # 解密函数
        res = base64.decodebytes(decrData.encode("utf-8"))
        msg_text = self.aes.decrypt(res)
        decrypt_text = self.unpad(msg_text).decode('utf8')
        return decrypt_text

def main():
    # 使用Syracuse作为key,9999999999999999作为iv对明文进行加密
    aes_key = "Syracuse"
    aes_iv = "9999999999999999"
    text_data = 'This is a top secret.'
    encrypt_data = EncryptDate(aes_key, aes_iv).encrypt(text_data)

    # 在words.txt中找到key
    # 寻找的方式就是使用该单词作为key,配合已知的iv进行解密,若得到的明文和已知的明文相同,则找到了key
    with open("words.txt") as f:
        for line in f.readlines():
            word = line.strip()
            try:
                decrypt_data = EncryptDate(word, aes_iv).decrypt(encrypt_data)
            except Exception as e:
                continue
            if(decrypt_data == text_data):
                print("原来key是:"+word)
                break;
if __name__ == '__main__':
    main()


  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值