一、引言

这仍然是信息安全课程的一次作业,老师的要求包括以源代码方式来安装openssl,了解AES和RSA加密算法并去尝试调用openssl库中AES和RSA算法的API,其实总体上安装以及实验还是比较容易的,不过还是踩了一些坑,这里还是记录一下,顺便试试CSDN的Markdown编辑器。

本文演示使用的操作系统为Ubuntu 16.04

二、安装

1.下载源码包

从官网上可以找到源码包的下载,这里我直接给出下载链接:
openssl源码包下载
根据官网的描述,1.1.1版本将是目前他们长期支持的版本,一直到2023年,建议使用1.0.x版本的用户也去安装这个最新版本。

2.编译安装

解压下载的源码包,可以看到如下的目录结构

可以点开INSTALL文件来查看安装说明,这里我们按照它说的最简说明方式来进行安装:

on Unix (again, this includes Mac OS/X):

$ ./config
$ make
$ make test
$ sudo make install

其中最后一条命令如果不是root用户执行,需要加上sudo,否则无法访问系统根目录的一些文件夹,至少我第一次没加sudo运行时报了错。

这四条命令运行完之后都没有报错的话,说明它的安装脚本中的所有任务都完成了,这时可以使用

openssl version

命令来查看当前openssl的版本,不过我在这时遇到了问题,报错是这样的:

openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

通过查找资料,这个问题也很容易就解决了,原因大概是因为libssl.so.1.1被安装脚本放置到了/usr/local/的lib下,而命令行调用的时候找的是/usr/的lib下的libssl.so.1.1,所以我们只需要用如下两条命令在/usr/的lib下创建链接文件即可:

ln -s /usr/local/lib/libssl.so.1.1 /usr/lib/libssl.so.1.1
ln -s /usr/local/lib/libcrypto.so.1.1 /usr/lib/libcrypto.so.1.1

值得一提的是,我百度到的命令的lib文件夹命名为lib64,这里一定要结合自己的情况去查看,不要直接复制命令去运行。

在解决这个问题之后,再运行之前的openssl version命令就会出现如下的显示,也说明安装成功了:

OpenSSL 1.1.1  11 Sep 2018

三、运行

1.MD5算法的实验

首先来实验一下最简单,也是最常用的MD5摘要算法,说它简单是因为它的API只有三个,用来试运行再好不过了,这里我也是参照了一位博主的一个例子来实验的,更详细的讲解可以看这篇博客:

Linux下C语言使用openssl库进行加密
用到的代码也是直接搬过来使用的,这里贴一下吧:

#include <openssl/md5.h>
#include <stdio.h>
#include <string.h>
int main()
{MD5_CTX ctx;unsigned char outmd[16];int i=0;memset(outmd,0,sizeof(outmd));MD5_Init(&ctx);MD5_Update(&ctx,"hel",3);MD5_Update(&ctx,"lo\n",3);MD5_Final(outmd,&ctx);for(int i=0;i<16;i++){printf("%02X",outmd[i]);}printf("\n");return 0;
}

这里是我遇到的另外一个坑,如果用gcc编译的话,会出现如下的情况:

$ gcc md5test.c
/tmp/ccP3aNqM.o:在函数‘main’中:
md5test.c:(.text+0x42):对‘MD5_Init’未定义的引用
md5test.c:(.text+0x58):对‘MD5_Update’未定义的引用
md5test.c:(.text+0x6e):对‘MD5_Update’未定义的引用
md5test.c:(.text+0x81):对‘MD5_Final’未定义的引用
collect2: error: ld returned 1 exit status

通过百度,这个问题也很好解决,只需要引用链接库crypto即可,如下所示:

$ gcc md5test.c -lcrypto && ./a.out
B1946AC92492D2347C6235B4D2611184

2. AES对称加密算法API调用实验

使用API之前,最好先简单了解一下AES算法的原理(虽然调用API的话并不需要搞清楚算法实现),这里我贴出一个博主的博客,感觉讲的还是挺好的
AES加密算法的详细介绍与实现
而实验部分的API我也参考了另一位博主的博客:
OPENSSL库的使用-AES篇

#include <openssl/aes.h>
#include <stdio.h>
int main()
{AES_KEY key;   //新建一个AES_KEYunsigned char userkey[]="test"; //密钥字串unsigned char in[]="this is data"; //要加密的信息unsigned char out[13];  //密文int res=AES_set_encrypt_key(userkey,128,&key); //设置加密秘钥AES_ecb_encrypt(in,out,&key,AES_ENCRYPT);   //设置解密秘钥puts(out);          //打印密文res=AES_set_decrypt_key(userkey,128,&key);   //设置解密秘钥unsigned char out2[13]; //保存解密后的字串AES_ecb_encrypt(out,out2,&key,AES_DECRYPT);   //解密puts(out2); //打印解密后的信息return 0;
}

这里的运行结果太鬼畜了,我贴一下图吧:

3.RSA算法API调用实验

RSA算法还是感觉挺神奇的,这里也是贴出一篇学习的时候参考的博客:
对称加密与非对称加密,以及RSA的原理
博主文尾举的例子好像有错误,我也在评论中写出来了,不过这篇文章依然极具参考价值。
实现部分,我参考了两位博主的代码:
OPENSSL库的使用-RSA篇
如何利用OpenSSL库进行RSA加密和解密

代码如下:

#include <openssl/rsa.h>
#include <stdio.h>
#include <string.h>
RSA * get_rsa(long e,int bit)
{RSA * rsa=RSA_new();  //新建RSA结构体指针if(rsa==NULL)return NULL;BIGNUM *eNum=BN_new();  //新建一个大数结构体对象if(!BN_set_word(eNum,e))   //设置算法中的ereturn NULL;if(!RSA_generate_key_ex(rsa,bit,eNum,NULL))    //调用API生成RSA结构体return NULL;return rsa;
}
int main()
{RSA *rsa=get_rsa(0x10001,1024);   //利用e为0x10001(65537)生成一个模数n为1024的rsa指针//RSA_print_fp(stdout,rsa,0);     //执行这句话可以打印出生成的十六进制格式的模数n、两个质数p、q等unsigned char in[]="Hello World";  //要加密的明文unsigned char out[2048];    //保存加密后的信息unsigned char res[120];   //保存解密后的信息,长度要小于RSA_size(rsa)//用于加解密传输:puts(in);  //打印明文printf("%d\n",RSA_public_encrypt(strlen(in)+1,in,out,rsa,RSA_PKCS1_PADDING));  //公钥加密明文生成密文puts(out);  //打印密文printf("%d\n",RSA_private_decrypt(128,out,res,rsa,RSA_PKCS1_PADDING));  //私钥解密密文puts(res);  //打印解密后的密文//用于签名和验签:printf("%d\n",RSA_private_encrypt(strlen(in)+1,in,out,rsa,RSA_PKCS1_PADDING));    //私钥加密明文生成密文puts(out);//打印密文printf("%d\n",RSA_public_decrypt(128,out,res,rsa,RSA_PKCS1_PADDING)); //公钥解密puts(res);    //打印解密后的密文RSA_free(rsa);    //释放rsa结构体内存return 0;
}

这里我封装了生成RSA结构体指针的过程,RSA指针中保存着之前原理中提过的n、p、q、e等BIGNUM类型的数据,似乎在1.1.1版本之前还可以查看值,但是我尝试去获取这些数据时会报错:

rsatest.c:20:32: error: dereferencing pointer to incomplete type ‘RSA {aka struct rsa_st}’
printf("%d\n",BN_num_bytes(rsa->n));

所以如果想查看rsa生成的东西的话,可以使用RSA_print_fp(stdout,rsa,0)函数,效果如下:

这里调用RSA_generate_key_ex(rsa,bit,eNum,NULL)传入的bit参数即为生成的rsa指针中的模数的位数,小于512的话会报段错误,其实我本来还想试试能不能生成原理中举的那个n为143的例子来着,看来也是根本不可能。

此外注意,保存解密后的信息的数组,长度要小于RSA_size(rsa)函数的返回值(违反这个规则的话是无法完成解密的,解密结果是乱码)我这里由于modulus(之前提到的bit参数)是1024,1024/8=128,所以长度设为了120,如果改变了modulus的大小,这里也要对应的改变。

最后来测试效果,也是比较鬼畜,所以直接截图了:


可见算法运行正确。

最后通过查阅相关资料得知,RSA加密算法有两种用途:

第一种用法:公钥加密,私钥解密。---用于加解密
第二种用法:私钥签名,公钥验签。---用于签名

openssl源代码方式安装以及简单的实验相关推荐

  1. 树莓派学习笔记—— 源代码方式安装opencv

    0.前言 本文介绍如何在树莓派中通过编译源代码的方式安装opencv,并通过一个简单的例子说明如何使用opencv. 更多内容请参考--[树莓派学习笔记--索引博文] 1.下载若干依赖项 在开始安装之 ...

  2. centos mysql安装包_Centos7下安装包方式安装MySQL

    安装包下载地址:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.27-1.el7.x86_64.rpm-bundle.tar 第一步:在 /h ...

  3. DHCP的安装到简单测试(tar方式)

    今天继续写一篇以tar方式安装DHCP服务器的文章.为什么用tar方式不用rpm,主要是因为我发现到网站上下载安装文件的时候,很难见到有最新rpm包的(等不及了,哈哈),况且网上有很多以rpm安装文章 ...

  4. *现在感觉librealsense和realsense-ros的安装挺简单的(普通X86平台)(现在发现都有两种安装方式,下载源码编译或者二进制安装)

    下面说的就是在普通X86平台上,不是在ARM平台,不在树莓派,TX2这些平台上. 之前潜意识里似乎还觉得会比较麻烦,实际我现在真正再看一下,回看一下,不是这样的.可能就像装双系统一样,实际并不麻烦,跟 ...

  5. Centos安装Nodejs简单方式

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时.本文主要讲的是如何在Linux即Centos上安装Nodejs的简单方式,有比设置环境变量更加简单的方式,那就是设 ...

  6. Linux编译和下载嵌入式实验,嵌入式实验6交叉编译及Linux简单程序设计实验

    <嵌入式实验6交叉编译及Linux简单程序设计实验>由会员分享,可在线阅读,更多相关<嵌入式实验6交叉编译及Linux简单程序设计实验(7页珍藏版)>请在人人文库网上搜索. 1 ...

  7. 通过二进制方式安装innobackupex

    目的 通过二进制方式安装innobackupex 环境 OS:CentOS 6.6 32bit 介绍 官网:https://www.percona.com/ 官方下载地址:https://www.pe ...

  8. python基础知识及数据分析工具安装及简单使用(Numpy/Scipy/Matplotlib/Pandas/StatsModels/Scikit-Learn/Keras/Gensim))

    Python介绍. Unix & Linux & Window & Mac 平台安装更新 Python3 及VSCode下Python环境配置配置 python基础知识及数据分 ...

  9. SVN客户端的安装和简单使用

    SVN介绍 SVN的全称是Subversion,即版本控制系统.它是最流行的一个开放源代码的版本控制系统.作为一个开源的版本控制系统,Subversion管理着随时间改变的数据.这些数据放置在一个中央 ...

最新文章

  1. wpf 为html 变量赋值_JavaScript 变量
  2. POJ 2533 Longest Ordered Subsequence
  3. Windows 2000本地路由表
  4. 从服务器上的数据库备份到本地
  5. jsp人事管理系统_Jsp+Ssm+Mysql实现的医院人事管理系统源码附带视频运行教程
  6. 多重共线性问题的几种解决方法
  7. 安卓3d游戏引擎_3D球闯关游戏-3D球闯关游戏安卓官方版预约 v1.2.5
  8. php为什么发送不到sql,PHP-为什么我的Ajax无法执行我的SQL查询?
  9. POJ 1984 Navigation Nightmare
  10. Boot2Docker 安装运行出现客户端与服务端版本不一致的解决办法
  11. 用来这么久的计算机,你是否对计算机中有关数及编码有掌握的呢???那么它来了,让你充分认识计算机有关数和编码的知识~~
  12. 08 Python 文件和数据格式化
  13. ACM/IOI 国家队集训队论文集锦
  14. 【Python】TX云服务器下CentOS+Python3+Nginx+uwsgi+Bottle搭建Web服务
  15. ERP系统应用的流程与步骤
  16. OEL安装RAC 配置DNS文档
  17. 排序算法总结(Python实现)——(一)
  18. android 自定义locale,android – 以编程方式设置Locale
  19. npm install --save 、--save-dev 、-D、-S的区别详细解说
  20. R语言统计与绘图:生存曲线的两两比较

热门文章

  1. 在wps里面怎么设置触发器_wps如何制作触发器
  2. 青龙面板最新版本2.10.11+(诺兰短信登录)nvjdc详细教程
  3. mysql安装教程 mac_Mac下MySQL安装配置教程
  4. Kafka 命令行工具 kcat/kafkacat
  5. “TikTok+独立站”模式熟了?看Anker如何玩转社交私域流量导流独立站?
  6. 阿里云进入Iot Studio
  7. C#实现Modbus协议与PLC通信
  8. 提高个人效率的方法和工具
  9. 应付模块的R12 TRACE 和 FND Debug 文件 / FND 日志 调试
  10. matlab ode 初值,关于ODE45初值问题和erf函数的问题