WIN10系统在VS2015配置OpenSSL
小学期要求做一个通信保密系统,安装配置OpenSSL遇到一些大坑,做一下笔记给自己吧。
下载OpenSSL
这里有很大的坑,官网下载的OpenSSL是没编译的,编译的过程极其繁琐;要下载编译好的OpenSSL才能使用直接使用,怎么办呢?还好有一个网站可以下载编译好的OpenSSL库:http://slproweb.com/products/Win32OpenSSL222.html。
(下载好的OpenSSL在运用的时候会有一些小问题,后面会说。)
下载网页截图
在VS2015中配置OpenSSL
如果你直接把引用到OpenSSL库的代码复制到源文件中,会有红色的标释提醒代码错误。
所以不仅仅要安装OpenSSL,还要在VS2015软件中配置一下才能用。关于配置的理解,我认为就是将OpenSSL文件的链接写清楚,以至于VS2015能够检测到OpenSSL中的函数。
话不多说,开始配置:
依次点击:项目—>属性—>配置属性—>VC++目录—>包含目录库—>编辑,
然后将OpenSSL的include文件位置填入。
include文件位置
配置
完成这一步再去编译代码,如果你能过了,应该就成功了。
不过的话,请看下面的错误解决办法
遇到的问题和解决方法
1,代码的问题
#pragma comment(lib,"libeay32.lib")
#pragma comment(lib,"ssleay32.lib")
原来找到的代码,给的lib链接是这样写的;出现下面的错误:
要改为具体的文件位置,比如我的libeay32.lib在 C:\\Program Files (x86)\\OpenSSL-Win64\\lib\\libeay32.lib中,所以要改为以下代码:
#pragma comment(lib,"C:\\Program Files (x86)\\OpenSSL-Win64\\lib\\libeay32.lib")
#pragma comment(lib,"C:\\Program Files (x86)\\OpenSSL-Win64\\lib\\ssleay32.lib")
fopen函数提示错误:
打开属性,点击C/C++,编辑预处理器定义,添加_CRT_SECURE_NO_WARNINGS
2,其他的问题
库计算机类型和目标计算机类型冲突:
目标计算机类型:
库计算机:
解决办法:都调为x64
还有一个问题是用到关于RSA的公私钥文件pem的时候回出现的问题:函数PEM_read_bio_PUBKEY等;
编译的时候没有错误,运行的时候窗口会一闪而过。通过单步调试才发现是pem类型的函数出现错误
查了资料说是要在本机编译OpenSSL才能解决,好像要改变引用的指针类型(比如BIO)也可以 解决。
https://blog.****.net/zuoyefeng1990/article/details/51578781(这篇博客有提到这种问题)
测试代码:
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <iostream>using namespace std;
#pragma comment(lib,"C:\\Program Files (x86)\\OpenSSL-Win64\\lib\\libeay32.lib")
#pragma comment(lib,"C:\\Program Files (x86)\\OpenSSL-Win64\\lib\\ssleay32.lib")void tSign()
{
unsigned char sign_value[1024]; //保存签名值的数组
int sign_len; //签名值长度
EVP_MD_CTX mdctx; //摘要算法上下文变量
char mess1[] = "xxh"; //待签名的消息
RSA *rsa = NULL; //RSA结构体变量
EVP_PKEY *evpKey = NULL; //EVP KEY结构体变量
int i;printf("正在产生RSA**...");
rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);//产生一个1024位的RSA**//printf ("bits: %d\n", BN_num_bits (rsa->n));//返回n的二进制位数!1024!
if (rsa == NULL)
{
printf("gen rsa err\n");
return;
}
printf(" 成功.\n");
//cout << "rsa **为:" << rsa << endl;
evpKey = EVP_PKEY_new();//新建一个EVP_PKEY变量
if (evpKey == NULL)
{
printf("EVP_PKEY_new err\n");
RSA_free(rsa);
return;
}
if (EVP_PKEY_set1_RSA(evpKey, rsa) != 1) //保存RSA结构体到EVP_PKEY结构体
{
printf("EVP_PKEY_set1_RSA err\n");
RSA_free(rsa);
EVP_PKEY_free(evpKey);
return;
}
//以下是计算签名代码
EVP_MD_CTX_init(&mdctx);//初始化摘要上下文
if (!EVP_SignInit_ex(&mdctx, EVP_md5(), NULL))//签名初始化,设置摘要算法,本例为MD5
{
printf("err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
if (!EVP_SignUpdate(&mdctx, mess1, strlen(mess1)))//计算签名(摘要)Update
{
printf("err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
//cout << "摘要为:" << &mdctx << endl;
if (!EVP_SignFinal(&mdctx, sign_value, (unsigned int *)&sign_len, evpKey)) //签名输出
{
printf("err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
printf("消息\"%s\"的签名值是: \n", mess1);
for (i = 0; i < sign_len; i++)
{
if (i % 16 == 0)
printf("\n%08xH: ", i);
printf("%02x ", sign_value[i]);
}
printf("\n");
EVP_MD_CTX_cleanup(&mdctx);printf("\n正在验证签名...\n");
//以下是验证签名代码
EVP_MD_CTX_init(&mdctx);//初始化摘要上下文
if (!EVP_VerifyInit_ex(&mdctx, EVP_md5(), NULL))//验证初始化,设置摘要算法,一定要和签名一致。
{
printf("EVP_VerifyInit_ex err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
if (!EVP_VerifyUpdate(&mdctx, mess1, strlen(mess1)))//验证签名(摘要)Update
{
printf("err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
if (!EVP_VerifyFinal(&mdctx, sign_value, sign_len, evpKey))//验证签名
{
printf("verify err\n");
EVP_PKEY_free(evpKey);
RSA_free(rsa);
return;
}
else
{
printf("验证签名正确.\n");
}
//释放内存
EVP_PKEY_free(evpKey);
RSA_free(rsa);
EVP_MD_CTX_cleanup(&mdctx);}
int main()
{
OpenSSL_add_all_algorithms();
tSign();
system("pause");
return 0;
}
参考博客:
https://blog.****.net/ljttianqin/article/details/72991125(配置OpenSSL)
https://blog.****.net/gpltoken/article/details/53011068(文章末尾有AES对文件进行加解密的程序,有任务的同学可以看一下)