南京邮电大学网络信息安全——OpenSSL加密数据实验(实验二)
- OpenSSL的下载和编译
- OpenSSL的下载
- OpenSSL的编译
- 解压
- 配置
- 编译
- 利用OpenSSL编程
- 编译测试文件
- 测试文件是否通过
- 设置环境变量(如果按照实验指南来进行安装,不需要设置环境变量)
- 加密测试
- 源码编写
- 编译和测试
- 利用Openssl进行加密
- 实验内容一:利用AES进行加密
- Base64编码部分
- 不同的加密方式
- 实验内容二:修改密文测试
- 实验内容三:RSA公钥和私钥的生产
- 实验内容四:数字签名
- 总结
OpenSSL的下载和编译
OpenSSL的下载
OpenSSL的下载链接为http://www.openssl/source/,在这里找到对应的下载方式
需要注意的是这里可能要搭个梯子,不然下载的可能会相当慢,当然也可以在国内找镜像也不是不可以。
需要注意的是下载的时候要找对版本,i386对应IA32架构(32位系统),amd64对应x86-64架构(64位系统)
这里说一点题外话就是amd64即x86-64架构(俗称的64位架构),由于该架构由amd提出并有inter发扬光大,所以有两个称呼。
OpenSSL的编译
解压
直接将下载好的内容放入Ubuntu即可。
然后执行一下解压命令
user1@ubuntu:~/Desktop$ tar -xzvf openssl-3.0.0-alpha6.tar.gz
这里的xzvf参数的含义如下:
- x:解压tar格式的文件
- v:解压时显示详细信息
- z:使用gzip程序解压
- f:使用归档
配置
解压完成后检查文件夹
在文件夹内运行
user1@ubuntu:~/Desktop/openssl-3.0.0-alpha6$ ./Configure
这里和原本的实验要输入的指令不太一样,原来的指令为:
./config –prefix=/usr/local
这里说一下,-perfix参数的意思是将软件的安装路径指定一下,我这里选择尊重Ubuntu的规范,不去修改他。同时写一下安装路径的默认规划为
文件类型 | 路径 |
---|---|
二进制文件 | usr\local\bin |
配置文件 | usr\local\etc |
库文件 | usr\local\local |
编译
在原来的文件夹里面运行make指令
user1@ubuntu: make & make install
这时屏幕上会出现大量的输出
等待输出完成,输入指令
user1@ubuntu: make test
可以看到正在进行测试。
需要注意的是在进行测试的过程中可能会出现某些错误,但是秉着够用就好的原则,我们这里不去关注他,因为这些功能我们可能是用不到的。并且最后的测试结果也是通过的。
然后执行命令,这个命令记得执行,不然找不到对应的头文件和动态库…这个地方我debug了好久
make install
利用OpenSSL编程
编译测试文件
测试文件源码如下
#include <stdio.h>
#include <evp.h>
int main()
{
printf("hello world!");
OpenSSL_add_all_algorithms();
return 0;
}
编译
user1@ubuntu:~/Desktop/OpenSSL_Test$ gcc test.c -I /usr/local/include/openssl/ -lcrypto
其中参数含义如下:
- -I:头文件路径
- -lxxx:在链接阶段链接动态库libxxx.so,如这里链接libcrypto.so文件
这里说一下如果直接按照实验指南里面的指令(不完全一致,修改了环境变量)
gcc test.c –o test –I /usr/local/openssl/include /usr/local/libcrypto.a –ldl
会发现在链接阶段无法通过
测试文件是否通过
编译完成后会出现以下的文件
直接运行,会出现找不到动态库的错误
原因在于Ubuntu的默认动态库搜索路径为/usr/lib,而我自定义的路径为/usr/local/lib里面,所以需要设置以下环境变量。
设置环境变量(如果按照实验指南来进行安装,不需要设置环境变量)
打开动态链接库配置文件
user1@ubuntu:~/Desktop/OpenSSL_Test$ sudo gedit /etc/ld.so.conf
添加自己的动态库路径
保存,并更新动态库缓存
sudo ldconfig
再次运行,即可成功
加密测试
源码编写
如果直接使用实验指南里面的源码的话会出现以下报错
经过查询发现在Openssl更新到1.1版本后,其API有一点点改变,修改后的源码如下
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
void tEVP_Encrypt()
{
unsigned char key[EVP_MAX_KEY_LENGTH];//密钥
unsigned char iv[EVP_MAX_KEY_LENGTH];//初始化向量
/* old usage*/
//EVP_CIPHER_CTX ctx;//EVP算法上下文
/* old usage*/
/*new usage*/
//EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
/*new usage*/
unsigned char out[1024];//输出密文缓冲区
int outl;//密文长度
int outltmp;
char *msg="Hello OpenSSL";//待加密的数据
int rv;
int i;
//设置key和iv(可以采用随机数和可以是用户输入)
for(i=0;i<24;i++)
{
key[i]=i;
}
for(i=0;i<8;i++)
{iv[i]=i;
}//初始化密码算法结构体
EVP_CIPHER_CTX_init(ctx);
//设置算法和密钥以及向量
rv = EVP_EncryptInit_ex(ctx,EVP_des_ede3_cbc(),NULL,key,iv);
if(rv!=1)
{
printf("Err\n");
return;
}
//数据加密
rv = EVP_EncryptUpdate(ctx,out,&outl,(const unsigned char*)msg,strlen(msg));
if(rv!=1)
{
printf("Err\n");
return;
}//结束数据加密,把剩余数据输出
rv = EVP_EncryptFinal_ex(ctx,out+outl,&outltmp);
if(rv!=1)
{
printf("Err\n");
return;
}
outl = outl +outltmp;
printf("Original text:%s\n",msg);
//打印输出密文
printf("Length of ciphertext:%d\n Data of ciphertext:\n",outl);
for(i=0;i<outl;i++)
{
printf("0x%02x ",out[i]);
}printf("\n");
}
int main()
{
OpenSSL_add_all_algorithms();
tEVP_Encrypt();
return 0;
}
编译和测试
/usr/bin/g++ -g /home/user1/Desktop/OpenSSL_Test/test2.cpp -o /home/user1/Desktop/OpenSSL_Test/test2 -I /usr/local/include/openssl/ -lcrypto
执行即可成功
利用Openssl进行加密
Openssl除了有编程接口外,还提供了命令行接口以便客户使用
实验内容一:利用AES进行加密
该实验有两个部分:
- 使用Base64和不使用Base64分别进行加密并观察结果
- 采用不同模式进行加密
Base64编码部分
首先说明一下Base64的作用,Base64基本上只做了一件事:将二进制数据编码成了ASCII码,以便于电子邮电阅读。知道这点就够了。
使用以下命令进行Base64加密
openssl enc -aes-256-cbc -salt -in lincoln.txt -out WithoutBase64.encn
其参数含义如下:
- enc:加密
- aes-256-cbc:采用aes算法进行加密,256位密钥,CBC模式
- salt:加盐
- in:输入文件
- out:输出文件
对于加密完成的文件,可以看到是一个二进制文件,无法直接打开。
利用二进制编辑软件打开,可以看到,其是一堆二进制乱码
也就是无法直接通过电子邮件,qq聊天框直接传递的。
利用以下指令执行Base64编码
openssl enc -aes-256-cbc -salt -a -in lincoln.txt -out WithBase64.encn
其中-a表示将密文用base64进行编码,加密结果如下,可以看到,这次就是可读文本了
不同的加密方式
为了方便起见,我这里都对密文采用了Base64编码。
首先采用CBC分组链接模式加密:
openssl enc -aes-256-cbc -salt -a -in lincoln.txt -out WithBase64CBC.encn
加密密文如下
EBC密码本加密模式进行加密
openssl enc -aes-256-ebc -salt -a -in lincoln.txt -out WithBase64EBC.encn
密文如下:
实验内容二:修改密文测试
我修改了密文文件,无论是修改还是增删都会出现报错
应该是OpenSSL的差错控制的报错吧,但也可能是我做的不太对…
实验内容三:RSA公钥和私钥的生产
OpenSSL的公私钥的生产分两个步骤:
- 生成私钥
openssl genrsa -out private.key
- 利用私钥生成公钥
openssl rsa -pubout -in private.txt -out public.txt
生成的私钥如下:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC49ZkZxQwo3ewJ
RHNco+9hfAeoxEZfoG4wGtznGInMYqGdivzhjCK3tBDWdl8bwiJUp6JqoRIeySwb
0xuG4KQMQ5uOtigrCPZ+Wcj5fs/Gve9tMLrT0xVtXltIdRCFuiXKPMJ9ava3oy7Q
cpEIBAhUneN/O+PLirZMmKODx9x46lKCab6T19VQM7f+dWi2aHsFqmQkccaaPSE3
nquRpF6bSggJh2US/v88tCUs7Z+VKpsoCEVumFXF28Nuq8VnLJddfO7KitRS4XWs
VdVNjwjWr2FRL/YzIayYDbJ614azr0uEyoEbT/NtW2AKYJMnqvNbybc55JSDOcLv
k6RVZ1HtAgMBAAECggEAOIjZg0b3sIYk37BMksSJJwMCVFOqLxCanZmYbArUE+US
AVW6djafZgdkHimQaKuuUrHqsy0InOBg2yBsCY4glp8TrUuAe6cBsR1AkQJyAA2O
YZHDiXu70PJGdJ9TrYx4gJiR2kQXpYn7hTt/mTOiWDrqjrl/p3d+wWrmkCFHAq4X
qpMuiBYIJNcKQa+LgUq71rHchjsNeDmKRdjId+4zBYWygcxoRL/p4cfhs7sWpk5n
5beGanFYhauTRxQzrsfsePQP3PLQSJljkXVhIFC0mASORR0WnYw3j3n6599scmRN
w6lpAU7JnTtXk3vS8CA7kXABCYAuhYHq9jSlOMgfAQKBgQDp8a0PRnj/qGiGDELk
e+PzbKArOHfCnGQJD+N0Kwd0t0jByJ4TY1poBwKSGP95o2byYQfSnssckiPkVeiH
VMY7EuYD5PzoTGdkUpIBfyOhlqABAd99x2AUPgR7/a689rZb+ewV6s+dw0/avSqs
K/c2uqGu97wx+hyAh0EnurtiMwKBgQDKZai8Cj66uwZMntoEA29NGa7IJ2Gi0zpk
OhhF6MblI+TABgl/RM21Cob/6dmRerJNU0cKgWOtdRjhuJCZozkHOC4dY3m268WR
NkbchqBMjqpJSQj1oHlZ1opOl9AyM1pDRkdbGoXrl/zxEuRwpStokeCjvaTObK/c
RZEdJfObXwKBgGTL0UHMnmOg3vAqpkOlsZB3VAdrPAZotZ1F8D1kMME0GzALTTiT
TSeXJZ9nD+QL6FY0QleYPXEg8j/2V8q/Vu2q9dnltqYsDTwna2sjqWl86ZGlifK6
jYYLNolpwvj935J/ex3yXuPdfDGF4bXu94PoI7OsX7S0y8UBAaypgwULAoGAGdog
UlxwpMNMy66ipE6YAd4c8B3vn6+hTroI7a0M8qnCBzD+N45fRBejJL8G9kkYyz2u
3k2moLpLQlGjzqwFlcF8Sm6xVkcJRkILjRF5Gi5C2/eDOHSV6362zdEgW7kpd1xb
suxRXMVeHqDOIwFF6SZw7hlEGsXRNK6CGZoGYrsCgYEAmQXSYcSU2WCF28fxFzNX
IB8G56o3iCPMUsdxkWeIVPRURjpY5QJ8G4r6LDZyltyRIcNEF3Ak/NiJL//LWbPQ
44KxH2KeIcOcTF6Nr65u8YFLHtUj4AUSgdjN4+jicxk2cOhwXzogpOKf4tRePYrc
mwi8n7PJhj2bgzoaxwULXnQ=
-----END PRIVATE KEY-----
公钥如下:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuPWZGcUMKN3sCURzXKPv
YXwHqMRGX6BuMBrc5xiJzGKhnYr84Ywit7QQ1nZfG8IiVKeiaqESHsksG9MbhuCk
DEObjrYoKwj2flnI+X7Pxr3vbTC609MVbV5bSHUQhbolyjzCfWr2t6Mu0HKRCAQI
VJ3jfzvjy4q2TJijg8fceOpSgmm+k9fVUDO3/nVotmh7BapkJHHGmj0hN56rkaRe
m0oICYdlEv7/PLQlLO2flSqbKAhFbphVxdvDbqvFZyyXXXzuyorUUuF1rFXVTY8I
1q9hUS/2MyGsmA2yeteGs69LhMqBG0/zbVtgCmCTJ6rzW8m3OeSUgznC75OkVWdR
7QIDAQAB
-----END PUBLIC KEY-----
在RSA算法里面,钥匙长度越长,消耗资源越多,对于一个数字签名来说,私钥只需要用一次,而公钥需要使用多次,所以从总体角度来说,私钥要比公钥长的多。
实验内容四:数字签名
使用以下指令进行数字签名
回顾以下数字签名的过程:首先进行Hash处理,后对Hash值进行签名
openssl dgst -sha1 -sign private.txt -out mytest.dig mytest
参数:
- dgst:digest,数字签名
- sha1:采用sha1进行hash
- sign:签名钥匙
需要指出的是签名为二进制序列,所以无法正常打开,并且Openssl在签名工具里面也没有提供Base64转码工具,以下是我的数字签名
验证签名采用如下指令
openssl dgst -sha1 -verify pubkey.pem -signature B13040450.sha1 B13040450
验证成功:
总结
总体来说,这次的实验虽然涉及到了Ubuntu下的编译和编程,但是可能由于openssl用的人比较多,编译过程中并没有“炼丹“。并且测试源码都已经给出了,所以总体来说比较简单。相较第一个实验来说,因为并没有涉及到软件的使用,所以并没有像使用WireShark时由于每个人的WireShark版本不一致导致实验难易不一。
需要注意的有两个点:
- 动态库名称及路径的设置,在这个实验里面要链接的动态库为libcrypto.so
- Openssl的API的变化
更多推荐
南京邮电大学网络信息安全——OpenSSL加密数据实验(实验二)
发布评论