[seed-labs] 密码技术应用实验
文章目录
实验目的
- 熟悉密钥加密与单向散列函数相关的概念
- 能够使用工具和编写程序来加 密/解密消息,为给定的消息生成单向散列值
实验原理
- 密钥加密。
- 加密模式、初始向量(IV)和填充(Padding)
- 使用加密算法的常见错误。 4. 使用密码库进行编程。
实验过程
环境设置
Task 1:使用不同的密码算法和加密模式加密
-
这里选用了最常用的
aes-128-cbc\des-cbc\des3
做加密
Task 2:加密模式:ECB vs. CBC
-
-
效果
-
结论:加密图片时使用cbc加密方式肉眼看不到原图片信息,儿ecb加密可以看到
Task 3:错误传播 – 被破坏的密文
-
一千字节文本我们可以使用给出的
plain.txt
文件 -
使用
AES-28
算法加密文件 -
损坏密文中的第55个字节,计算十六进制表示为
0x36 ,这里我改为了
00`ECB
CBC
-
用正确的密钥解密损坏的密文
ECB
CBC
-
这个vim一转头解码方式就变了,给我搞成汉字生僻字,拿vscode打开一看改动的字符仅影响几位,且ECB影响看起来较小。1字节=8bit,我推测ECB扰动16bit,CBC扰动16bit
-
通过资料查找,我发现在CBC模式中,它仅由当前的128bit分组的那一个字节受到影响,即文中的
or
-
ECB模式中,它每个128bit分组都会受到影响,具体在之后的空格、
i
等都有受到
Task 4:寻找密钥
-
from Crypto import Random from Crypto.Cipher import AES Cipher=bytes.fromhex("7827baf49c2464156528d99a0fcda1c714d7cb591fbed2364c41a9fc03596cc4") Iv=bytes.fromhex("010203040506070809000a0b0c0d0e0f") if __name__=='__main__': f=open("words.txt","r") key=f.readline().strip('\n') while key: if len(key)<16: key+='#'*(16-len(key)) key=key.encode() aes=AES.new(key,AES.MODE_CBC,Iv) plain=aes.decrypt(Cipher) if plain[:21]=='This is a top secret.'.encode(): print(key) key=f.readline().strip('\n') f.close()
-
-
key是wizard
Task 5:生成消息摘要
- 观察到MD5长度128位,SHA1长度160位,SHA256长度256位
Task 6:哈希函数的输出特性
-
修改后:
-
-
H1与H2完全不相同
Task 7:单向性与抗碰撞性
-
#include <stdio.h> #include <string.h> #include <openssl/sha.h> #include <time.h> #include <stdlib.h> #define len 16 #define SHA_DIGEST_LENGTH 20 int main() { const unsigned char allChar[63] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; char str1[7]="4dc981"; char string[len]; string[15]='\x0a'; srand((unsigned int)time(NULL)); int count=0; int finall=0; while(1) { count++; for(int i=0;i<15;i++) { int j=rand()%62; string[i]=allChar[j]; } unsigned char digest[SHA_DIGEST_LENGTH]; SHA1((unsigned char*)&string, 16, (unsigned char*)&digest); char mdString[SHA_DIGEST_LENGTH*2+1]; for(int i = 0; i < SHA_DIGEST_LENGTH; i++) sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]); int count1=0; for(int i=0;i<6;i++) { if(mdString[i]==str1[i]) {count1++;} } if(count1==6) {finall++; for(int i=0;i<16;i++) printf("%c",string[i]);} if(finall==5) break; } printf("time is :%d\n",count/5); return 0; }
-
编译:
gcc task7.c -o task7 -lcrypto
-
结果:
计算平均值大约为
16918381
,文本内容如上图