私钥加密实验
Section outline
-
-
把 zip 文件下载到 VM 里, 然后用 unzip 命令解压缩。
-
-
众所周知,单表替换密码是不安全的,因为可以通过字母的频率分析来破译。本实验为你提供了一个使用单表替换密码加密的密文。也就是说,原始文本中的每个字母都由另一个字母替换,而替换的字母是不变的(即在加密过程中,一个字母始终被同一字母替换)。你的任务是使用频率分析来破译这段密文,我们已知原始文本是英文文章,密文在 Labsetup.zip 文件中。我们在 Labsetup/Files 文件夹中提供了一个 Python 程序 ( freq.py}),它读取 ciphertext.txt 文件,并生成 n-gram 的统计数据,包括单字母频率、二元词组频率(2 个字母序列)和三元词组频率(3 个字母序列)等。
$ ./freq.py ------------------------------------- 1-gram (top 20): n: 488 y: 373 v: 348 ... ------------------------------------- 2-gram (top 20): yt: 115 tn: 89 mu: 74 ... ------------------------------------- 3-gram (top 20): ytn: 78 vup: 30 mur: 20 ...
使用频率分析,你可以很容易地找到某些字符的明文。对于这些字符,你可能希望将其改回明文,因为这样可能会获得更多线索。最好对明文使用大写字母,这样对于同一字母,我们知道哪个是明文,哪个是密文。你可以使用 tr 命令来执行此操作。例如,下面我们将 in.txt 中的字母 a, e 和 t 分别替换为字母 X, G, E, 结果保存在 out.txt 中。$ tr 'aet' 'XGE' < in.txt > out.txt
英文字母、二元组、和三元组出现的频率可以参考本章节的资源。 -
在此任务中,我们将使用各种加密算法和模式。你可以使用以下 openssl enc 命令来加密、解密文件,可以输入 man openssl 和 man enc 来查看手册。
$ openssl enc -ciphertype -e -in plain.txt -out cipher.bin \ -K 00112233445566778889aabbccddeeff \ -iv 0102030405060708
请用具体的密码类型替换 ciphertype,例如 -aes-128-cbc, -bf-cbc,-aes-128-cfb 等。在本任务中,你应该尝试至少 3 种不同的密码算法。你可以通过输入 man enc 来找到命令行选项的含义以及支持的所有密码类型。我们在下面列出了 openssl enc 命令的一些常用选项:-in <file> 输入文件 -out <file> 输出文件 -e 加密 -d 解密 -K/-iv 后面跟着 key/iv (16 进制) -[pP] 打印 iv/key (-P 代表退出)
-
Labsetup.zip 文件中包含的 pic_original.bmp 是一张简单的图片。我们希望对这张图片进行加密,使没有密钥的人无法知道图片中的内容。请分别使用 ECB (电子密码簿)和 CBC (密码块链接)模式加密文件,然后执行以下操作:
- 我们需要先处理一下加密后的图片,这样可以用图片显示程序来显示图像。bmp 文件的前 54 个字节包含有关图片的信息头,这些信息必须正确,否则没法显示。头部信息虽然也是被加密了,这些信息并不难得到。为了方便起见,我们用原始图片的头部替换加密图片的头部。你可以使用十六进制编辑器来直接修改二进制文件,也可以使用以下命令从 p1.bmp 获取头部数据,从 p2.bmp 获取加密的图片数据(从偏移量 55 到文件末尾),然后将它们组合成一个新文件。
$ head -c 54 p1.bmp > header $ tail -c +55 p2.bmp > body $ cat header body > new.bmp
- 显示加密的图片。我们在 VM 上安装了一个名为 eog} 的图片显示程序。你能从加密图片中获取有关原始图片的有用信息吗?请解释你观察到的现象。
请你自己选择一张图片,重复上面的实验并报告你观察到的现象。 - 我们需要先处理一下加密后的图片,这样可以用图片显示程序来显示图像。bmp 文件的前 54 个字节包含有关图片的信息头,这些信息必须正确,否则没法显示。头部信息虽然也是被加密了,这些信息并不难得到。为了方便起见,我们用原始图片的头部替换加密图片的头部。你可以使用十六进制编辑器来直接修改二进制文件,也可以使用以下命令从 p1.bmp 获取头部数据,从 p2.bmp 获取加密的图片数据(从偏移量 55 到文件末尾),然后将它们组合成一个新文件。
-
对于分组密码,当明文的大小不是分块大小的倍数时,可能需要填充。PKCS #5 填充方案被许多分组密码算法广泛使用。我们将通过以下实验来了解这种填充的是怎样工作的:首先,分别使用 ECB 、 CBC 、 CFB 和 OFB 模式加密一个文件(可以选择任何加密算法)。请报告哪些模式有填充,哪些没有。对于那些不需要填充的工作模式,请解释为什么它不需要填充。然后创建三个文件,分别包含 5 个字节, 10 个字节和 16 个字节。可以使用以下 echo -n 命令创建此类文件。下面的示例创建了一个长度为 5 的文件 f1.txt(如果不带 -n 选项,长度会是 6 ,因为 echo 会添加一个换行符):
$ echo -n "12345" > f1.txt
接下来我们通过 “openssl enc -aes-128-cbc -e” 命令来使用 128-bit AES 算法和 CBC 模式加密这三个文件。请描述加密后的文件的大小。观察在加密的过程中填充了哪些内容。使用 openssl enc -aes-128-cbc -d 命令可以解密这些文件。但是,默认情况下解密过程中会去除这些填充,导致我们无法看到填充的内容。好在该命令有一个 -nopad 选项,可以在解密的过程中不去除填充的数据。因此,通过查看解密后的数据,我们可以看到填充的数据。请用这种方法找出这三个文件被添加了哪些填充数据。注意,填充的数据可能无法打印出来,你需要使用十六进制工具来显示这些数据。下面的例子展示了如何用十六进制的格式显示一个文件。$ hexdump -C p1.txt 00000000 31 32 33 34 35 36 37 38 39 49 4a 4b 4c 0a |123456789IJKL.| $ xxd p1.txt 00000000: 3132 3334 3536 3738 3949 4a4b 4c0a 123456789IJKL.
-
对 IV 的基本要求是"唯一性",即对于同一个密钥, IV 不能重复使用。为了理解其中原因,请使用 (1) 两个不同的 IV (2) 相同的 IV 加密相同的明文。请描述你观察到的现象。有人可能会争辩说,如果明文不重复,那么使用相同的 IV 是安全的。让我们看一下输出反馈( OFB )模式。假设攻击者知道了明文( P1} )和密文( C1} )。如果 IV 始终相同,他/她可以破解其他的加密消息吗?请尝试根据下面提供的 P1 和 C1,对 C2 进行破译,找到它的明文 P2。
Plaintext (P1): This is a known message! Ciphertext (C1): a469b1c502c1cab966965e50425438e1bb1b5f9037a4c159 Plaintext (P2): (内容你不知道) Ciphertext (C2): bf73bcd3509299d566c35b5d450337e1bb175f903fafc159
在本实验中,如果我们用 CFB 替换 OFB,有多少 P2 会被泄露?你只需要回答这个问题,不需要论证。本实验中使用的攻击方式被称为“已知明文攻击”。在这种密码分析攻击模型中,攻击者既可以获得一定数量的明文和对应的密文。如果这种攻击能导致进一步的秘密泄露,那么加密方案就被认为是不安全的。示例代码。我们提供了一个名为 sample_code.py 的示例程序,该程序可在 Labsetup/Files 文件夹中找到。它展示了如何对字符串(ascii 字符串和十六进制字符串)进行异或运算。代码如下所示:#!/usr/bin/python3 # XOR two bytearrays def xor(first, second): return bytearray(x^y for x,y in zip(first, second)) MSG = "A message" HEX_1 = "aabbccddeeff1122334455" HEX_2 = "1122334455778800aabbdd" # Convert ascii/hex string to bytearray D1 = bytes(MSG, 'utf-8') D2 = bytearray.fromhex(HEX_1) D3 = bytearray.fromhex(HEX_2) r1 = xor(D1, D2) r2 = xor(D2, D3) r3 = xor(D2, D2) print(r1.hex()) print(r2.hex()) print(r3.hex())
-
从前面的任务中,我们已经知道了 IV 不能重复。对 IV 的另一个重要要求是,IV必须是不可预测的,即IV必须随机生成。在此任务中,我们会看到如果 IV 是可预测的,将会发生什么后果。
假设 Bob 刚刚发出一条加密的消息,Eve 知道这条消息的内容要么是 Yes,要么是 No。Eve 可以看到密文和加密该消息使用的 IV ,但是由于 AES 加密算法强度很高,Eve 不知道实际的内容是什么。但是,因为 Bob 使用了可以预测的 IV , Eve 知道 Bob 会用的下一个 IV 是什么。
一个好的加密算法不仅应该抵御前面描述的已知明文攻击,还应该抵御"选择明文攻击" 。这是一种密码分析的攻击模型,在这种模型中攻击者可以获得任意明文的密文。由于 AES 是可以抵御选择明文攻击的强密码,因此 Bob 不介意加密 Eve 提供的任何明文。他每次加密确实使用了不同的 IV,但是他用的 IV 不是随机的,是可以预测。
你的工作是构造一条消息,请 Bob 对其进行加密并提供密文。你要利用这次机会确定 Bob 的秘密消息的实际内容是 Yes 还是 No 。在此任务中,我们提供了一个加密 Oracle,它可以模拟 Bob 并使用 128 位 AES 和 CBC 模式进行加密。你可以通过运行以下命令来访问 Oracle:$ nc 10.9.0.80 3000 Bob's secret message is either "Yes" or "No", without quotations. Bob's ciphertex: 54601f27c6605da997865f62765117ce The IV used : d27d724f59a84d9b61c0f2883efa7bbc Next IV : d34c739f59a84d9b61c0f2883efa7bbc Your plaintext : 11223344aabbccdd Your ciphertext: 05291d3169b2921f08fe34449ddc3611 Next IV : cd9f1ee659a84d9b61c0f2883efa7bbc Your plaintext : <your input>
在显示出下一个 IV 之后,谕示器会要求你输入下一条明文消息(以十六进制字符串的格式),然后加密这条消息,并输出新的密文。加密时 IV 每次都会变,但其值是可以预测的。为了简化你的工作,我们让 Oracle 输出下一个 IV 。按 Ctrl+C 即可退出交互。 -
此任务主要使为了计算机专业或需要编程的相关领域学生设计的。学生应当和教师确认在他们的课程中是否要求完成此任务。在此任务中,我们提供给了一个明文和一个密文,你的任务是找出加密使用的密钥。你知道以下信息:
- 加密使用了 aes-128-cbc 算法。
- 加密此明文使用的密钥是一个少于 16 个字符的英语单词。这个单词可以从英语字典中找到。由于这个单词少于 16 个字符(即 128 bits,秘钥的长度),在单词的结尾附加了一些井号(#:十六进制值是 0x23)构成一个 128 bits 的密钥。
你的目标是写一个程序找出加密密钥。你可以从网络上下载一个英语单词表。我们在 Labsetup.zip 文件中也附带了一个英语单词表。明文、密文和 IV 如下所示:Plaintext (total 21 characters): This is a top secret. Ciphertext (in hex format): 764aa26b55a4da654df6b19e4bce00f4 ed05e09346fb0e762583cb7da2ac93a2 IV (in hex format): aabbccddeeff00998877665544332211
需要注意以下问题:- 如果你选择把明文存储在一个文件里,然后将文件输入到程序中,你需要检查文件的长度是否为 21 。如果你在文本编辑器中输入这条消息,有些编辑器会在文件的末尾添加一个特殊字符。存储消息最简单的方法是使用下面的命令(-n 标志使 echo 不在末尾添加换行符):
$ echo -n "This is a top secret." > file
- 在此任务中,你应当编写自己的程序来调用密码库。如果你只是简单地使用 openssl 命令完成此任务,将不会得分。可以在下面的链接中找到示例代码:
https://www.openssl.org/docs/man1.1.1/man3/EVP_CipherInit.html
- 当你使用 gcc 编译代码时,不要忘记加上 -lcrypto 选项。因为代码需要 crypto 库。参见下面的例子:
-
$ gcc -o myenc myenc.c -lcrypto
-
你需要提交一份带有截图的详细实验报告来描述你所做的工作和你观察到的现象。你还需要对一些有趣或令人惊讶的观察结果进行解释。请同时列出重要的代码段并附上解释。只是简单地附上代码不加以解释不会获得学分。实验报告的提交方式会由你的老师进行具体安排。