信息安全技术实验报告基于openssl库的对称密码实验.docx
《信息安全技术实验报告基于openssl库的对称密码实验.docx》由会员分享,可在线阅读,更多相关《信息安全技术实验报告基于openssl库的对称密码实验.docx(12页珍藏版)》请在冰豆网上搜索。
信息安全技术实验报告基于openssl库的对称密码实验
信息安全技术实验报告
姓名:
xxx
学号:
xxxxxxxxx
专业:
xxxxx
日期:
xxxxxx
Lab2:
基于openssl库的对称密码实验
一、实验目的
让学生熟悉加密的概念,熟悉和了解加密算法(cipher)、加密模式(encryptionmode)、以及初始向量(IV)的定义与作用。
二、实验环境
1.虚拟机VirtualBox
2.Ubuntu-16.04.6
3.bless十六进制编辑器
三、实验内容
3.1使用opensslenc命令来加密/解密一个文件。
命令基本格式如下:
$opensslenc-eciphertype-inplain.txt-outcipher.bin-K00112233445566778899aabbccddeeff
010*********
了解openssl命令的基本格式中各个参数和选项的含义,然后将上述命令代码中的ciphertype替换成指定的加密类型,比如-aes-128-cbc,-aes-128-cfb,-bf-cbc等,也可以替换命令实例中的参数K和iv。
实验报告中相关问题的回答:
1.配置好实验环境,查看openssl版本。
图3.1.1查看openssl版本
2.创建一个文本文件,并任意输入内容,保存后作为输入文件,执行上面的命令行中的加密命令,然后使用对应的解密命令解密加密文件,并对比解密后的输出和原始输入文件是否相同。
创建一个文本文件plain.txt,并输入内容“Iloveyou”,作为输入文件。
这里使用的加密类型为-aes-128-cbc。
加密操作如下:
$opensslenc-e-aes-128-cbc-inplain.txt-outcipher.bin-K00112233445566778899aabbccddeeff
010*********
图3.1.2-1文本加密
解密操作如下:
$opensslenc-d-aes-128-cbc-incipher.bin-outdcipher.txt
-K00112233445566778899aabbccddeeff010*********
图3.1.2-2文本解密
结论:
解密后的输出和原始输入文件相同。
3.不同工作方式对是否会对明文进行填充?
编辑一个文档word.odt,并加密。
1)第一种,使用的加密类型为-aes-128-cbc具体操作如下:
$opensslenc-e-aes-128-cfb-inword.odt-outwordcfb.bin-K0123456-iv789
图3.1.3-1第一种加密
结论:
加密后生成的文档大小和原来的明文大小一致。
2)第二种,使用的加密类型为-aes-128-cbc具体操作如下:
$opensslenc-e-aes-128-cbc-inword.odt-outwordcbc.bin-K0123456-iv789
图3.1.3-2第二种加密
结论:
加密后生成的文档大小和原来的明文大小一致。
3)第三种,使用的加密类型为-bf-cbc具体操作如下:
$opensslenc-e-bf-cbc-inword.odt-outwordbf.bin-K0123456-iv789
图3.1.3-3第三种加密
结论:
加密后生成的文档大小和原来的明文大小一致。
4.ecb和cbc两个工作方式对bmp图片的加密效果比较。
以picture.bmp图片作为输入文件,分别采用aes-128-ecb方式和aes-128-cbc方式加密并输出为图像文件。
具体操作如下:
$opensslenc-e-aes-128-ecb-inpicture.bmp-outpictureecb.bmp-K0123456
$opensslenc-e-aes-128-cbc-inpicture.bmp-outpicturecbc.bmp-K0123456-iv789
图3.1.4-1两种加密过程
因加密后的文件不能正常显示为图像,所以使用bless打开两个图像文件,修改其前缀为标准的图像文件前缀:
图3.1.4-2用bless修改加密后的文件1
图3.1.4-3用bless修改加密后的文件2
修改后的两个图像及原图片对比如下:
图3.1.4-4加密后的图片同原图的对比
简要描述ecb和cbc工作方式:
ecb是最简单的块密码加密模式,加密前根据加密块大小(如AES为128位)分成若干块,之后将每块使用相同的密钥单独加密,解密同理。
cbc模式对于每个待加密的密码块在加密前会先与前一个密码块的密文异或然后再用加密器加密。
第一个明文块与一个叫初始化向量的数据块异或。
结论:
由图可以看出,cbc方式加密得到的图片跟原图差距很大,原图的线条及颜色都被隐藏得很好:
而ecb方式加密得到的图片还保留了原图的线条形状,只是颜色发生了改变。
3.2使用Openssl加密库进行编程
在本实验中,将学习如何使用openssl的加密库来加密/解密信息,openssl提供一个叫作EVP的高级接口,已封装底层函数,尽管openssl也为每一个单独的加密算法提供接口,但使用evp会更方便一些。
实验具体内容:
已知明文和密文,如下所示。
并且已知加密方法为aes-128-cbc,IV全由0组成,以及key是字典word.txt(实验提供)中的一个英文单词,其长度小于16个字母,由于该单词小于16个字母128bits所以在其后追加了空格字符对应(0x20)以达到128bit的长度。
实验报告中的问题:
1.写一个穷举攻击的程序找到加密密钥key,解密密文,使得解密的结果与明文相同。
明文(21个字符):
Thisisatopsecret.
密文(十六进制形式):
8d20e5056a8d24d0462ce74e4904c1b513e10d1df4a2ef2ad4540fae1ca0aaf9
1)这里使用的是实验提供的key.c,编译key.c:
$gcc-I/usr/include/openssl-L/usr/lib/ssl-oenckey.c-lcrypto-ldl
图3.2.1-1key.c的编译
2)给程序key.c中每条语句添加注释
#include//调用openssl库头文件
#include//调用openssl库头文件
#include//调用openssl库头文件
#include//调用字符串头文件
#include//调用标准输入输出函数头文件
#include//调用standardlibrary标准库头文件
#defineTrue1//定义正确返回1
#defineFalse0//定义错误返回0
voidhandleErrors(void)//过滤异常
{
ERR_print_errors_fp(stderr);//将错误信息打印到FILE中
abort();//终止
}
intencrypt(unsignedchar*plaintext,intplaintext_len,unsignedchar*key,
unsignedchar*iv,unsignedchar*ciphertext)//声明加密函数
{
EVP_CIPHER_CTX*ctx;//加解密接口函数
intlen;//声明长度len
intciphertext_len;//声明密文长度ciphertext_len
//EVP_CIPHER_CTX_set_padding(ctx,0);
if(!
(ctx=EVP_CIPHER_CTX_new()))
handleErrors();//操作成功返回1,否则返回0
if(1!
=EVP_EncryptInit_ex(ctx,EVP_aes_128_cbc(),NULL,key,iv))//初始化ctx
handleErrors();//操作成功返回1,否则返回0
if(1!
=EVP_EncryptUpdate(ctx,ciphertext,&len,plaintext,plaintext_len))//如果要加密的数据大小是算法块大小的整数倍执行如下的if分支。
直接调用EVP算法加密函数进行加密
handleErrors();//操作成功返回1,否则返回0
ciphertext_len=len;
if(1!
=EVP_EncryptFinal_ex(ctx,ciphertext+len,&len))//处理最后没加密完的数据
handleErrors();//操作成功返回1,否则返回0
ciphertext_len+=len;//ciphertext_len=ciphertext_len+len
EVP_CIPHER_CTX_free(ctx);
returnciphertext_len;//返回密文长度
}
intappend(char*buffer){
intlength=(int)strlen(buffer);//声明length为循环数组的长度
if(length>16)//如果长度>16个字符
returnFalse;//报错
memset(buffer+strlen(buffer),'',16-length);//指定数组长度为16个字符
buffer[16]='\0';//buffer[16]为空
returnTrue;//返回正确结果
}
intmain(intargc,charconst*argv[])
{
charbuffer[50];//声明循环数组
inti=0;//声明i为0
chariv[17];//声明字符串iv
memset(iv,0,17);//设置数组起始地址为iv,每个字节的值为0,数组长度为17
unsignedchar*plaintext="Thisisatopsecret.";//加密输入串
unsignedcharciphertext[100];//声明无符号类型字符串数组
unsignedchar*cryptotext="8d20e5056a8d24d0462ce74e4904c1b513e10d1df4a2ef2ad4540fae1ca0aaf9";//输入密文
ERR_load_crypto_strings();//加载所有摘要和密码算法
OpenSSL_add_all_algorithms();//加载加密算法函数和单向散列算法函数
OPENSSL_config(NULL);
intciphertext_len;//声明ciphertext_len
intk=0;//声明k
FILE*fp=fopen("words.txt","r");//打开word.txt文件
while(fscanf(fp,"%s\n",buffer)!
=EOF){//当文件未结束时进入循环
k++;
if(!
append(buffer))//如果未连接到数组
continue;//继续循环
ciphertext_len=encrypt(plaintext,strlen(plaintext),buffer,iv,ciphertext);
unsignedcharcryptohex[50];
for(i=0;i{
sprintf(cryptohex+i*2,"%02x",ciphertext[i]);//每个字符打印二位16进制数
}
cryptohex[ciphertext_len*2]='\0';
if(0==strcmp(cryptohex,cryptotext)){//比较cryptohex和cryptotext若一致
printf("Thekeyis:
%s,cryptohexis%s\n",buffer,cryptohex);//打印密钥和密文
break;
}//打印密钥和密文
}
//printf("kis%d\n",k);
EVP_cleanup();
ERR_free_strings();
return0;
}
3)运行程序
图3.2.1-2运行代码
4)程序运行的流程图
图3.2.1-3程序运行流程图
2.结对伙伴中的一方使用字典中的一个单词加密一段明文,加密后,将明、密文发给对方,接收方运行程序,找到加密密钥。
双方可以互换角色,并验证对方找到的密钥是否正确。
1)发送给结对伙伴xxx的明密文信息如下:
明文:
everything that kills me makes me feel alive
密文:
9505a817388355b7c78a5c61c14c18fbd99b6eac14d9a9dd2d0b912523aa9cd86926876c57754375ae2964a3732bab1f
密钥:
absorb
图3.2.2-1使用字典中的一个单词加密一段明文
经验证,结对伙伴所获得的密钥正确。
2)接收到结对伙伴xxx发来的明密文信息:
明文:
vae
密文:
37882edba436aae68387d91e8aba89f1
图3.2.2-2找到结对伙伴使用的密钥
经结对伙伴验证,密钥正确。
四、实验总结
序号
遇到的问题
问题的解决方法
1
最开始选用Windows系统作为实验环境,在安装WinGW时,需要在线下载安装,但总是连接不到服务器,且耗时长
改用虚拟机和linux平台为实验环境,并在Ubuntu中下载了openssl库
2
在进行对文本文档加解密的实验中,解密所获得的文本文档打开后内容总是乱码
后来发现是因为解密命令中同时写了-d和-e,这是我对于加解密的命令格式不熟悉造成的
3
在进行加密bmp文件的实验中,希望Ubuntu可以共享Windows系统内存放的bmp文件
在Ubuntu中下载了samba,途中又试了很多种办法,都有些坎坷,但是最后发现已经实现了文件共享
4
在进行加密bmp文件的实验中,两种加密方式获得的文件都不能正常显示成图片,用bless打开后,不知如何修改前缀
在实验楼中找到了修改方法
收获:
这次的实验我花了大概一周时间来做,感觉难度较大,但是通过这几天在网上查阅各种资料,收获了很多知识,在加解密算法和c语言等方面有了更加深入的了解。
结对伙伴向我请教问题时,我也能在一定程度上给予帮助,有很大的成就感,每次实验作业的完成都能给我带来很大的鼓舞,希望在今后的实验任务中也能迎难而上,永不放弃。