最近工作需要使用一些加密算法。之前尝试过cryptopp以及polarssl,听说openssl中的加密模块特别全,并且特别好用。于是想尝试一下。

一、环境配置

下载openssl,我这里使用的是openssl-1.0.1s。解压后查看自带的win32说明文件。我这里解压到d盘

按照安装说明下载activeperl

二、编译静态库

执行命令:

cd D:\openssl-1.0.1s
D:
perl Configure VC-WIN32 no-asm --prefix=D:\openssl-1.0.1s
ms\do_ms

有类似输出

然后打开vs2010命令行工具

cd d:\openssl-1.0.1s
d:
nmake -f ms\nt.mak

等待几分钟,完成后在\out32目录下有静态库文件。

说明:

1.若想生成dll 则将ms\nt.mak 改为ms\ntdll.mak

2.默认情况下,静态库使用的是MT,动态库使用的是MD

3.若想指定MT或MD,修改nt.mak或ntdll.mak 对应CFLAG=内容。

4.若想生成Debug版本的静态库,perl选项设置中修改VC-WIN32为debug-VC-WIN32

三、使用静态库

新建控制台项目

切换Debug生成选项为release

在项目--属性--VC++目录包含目录添加

D:\openssl-1.0.1s\inc32

库目录添加

D:\openssl-1.0.1s\out32;

在项目--属性--C++--连接器--代码生成中修改MD为MT

测试RSA加密解密代码如下:

// testOpenssl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <stdio.h>
#include <stdlib.h> #include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <fstream>
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib") // 生成公钥文件和私钥文件,私钥文件带密码
int generate_key_files(const char *pub_keyfile, const char *pri_keyfile,
const unsigned char *passwd, int passwd_len)
{
RSA *rsa = NULL;
rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
if(rsa == NULL)
{
printf("RSA_generate_key error!\n");
return -1;
} // 开始生成公钥文件
BIO *bp = BIO_new(BIO_s_file());
if(NULL == bp)
{
printf("generate_key bio file new error!\n");
return -1;
} if(BIO_write_filename(bp, (void *)pub_keyfile) <= 0)
{
printf("BIO_write_filename error!\n");
return -1;
} if(PEM_write_bio_RSAPublicKey(bp, rsa) != 1)
{
printf("PEM_write_bio_RSAPublicKey error!\n");
return -1;
} // 公钥文件生成成功,释放资源
printf("Create public key ok!\n");
BIO_free_all(bp); // 生成私钥文件
bp = BIO_new_file(pri_keyfile, "w+");
if(NULL == bp)
{
printf("generate_key bio file new error2!\n");
return -1;
} if(PEM_write_bio_RSAPrivateKey(bp, rsa,
EVP_des_ede3_ofb(), (unsigned char *)passwd,
passwd_len, NULL, NULL) != 1)
{
printf("PEM_write_bio_RSAPublicKey error!\n");
return -1;
} // 释放资源
printf("Create private key ok!\n");
BIO_free_all(bp);
RSA_free(rsa); return 0;
}
// 打开公钥文件,返回EVP_PKEY结构的指针
EVP_PKEY* open_public_key(const char *keyfile)
{
EVP_PKEY* key = NULL;
RSA *rsa = NULL; OpenSSL_add_all_algorithms();
BIO *bp = BIO_new(BIO_s_file());;
BIO_read_filename(bp, keyfile);
if(NULL == bp)
{
printf("open_public_key bio file new error!\n");
return NULL;
} rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
if(rsa == NULL)
{
printf("open_public_key failed to PEM_read_bio_RSAPublicKey!\n");
BIO_free(bp);
RSA_free(rsa); return NULL;
} printf("open_public_key success to PEM_read_bio_RSAPublicKey!\n");
key = EVP_PKEY_new();
if(NULL == key)
{
printf("open_public_key EVP_PKEY_new failed\n");
RSA_free(rsa); return NULL;
} EVP_PKEY_assign_RSA(key, rsa);
return key;
} // 打开私钥文件,返回EVP_PKEY结构的指针
EVP_PKEY* open_private_key(const char *keyfile, const unsigned char *passwd)
{
EVP_PKEY* key = NULL;
RSA *rsa = RSA_new();
OpenSSL_add_all_algorithms();
BIO *bp = NULL;
bp = BIO_new_file(keyfile, "rb");
if(NULL == bp)
{
printf("open_private_key bio file new error!\n"); return NULL;
} rsa = PEM_read_bio_RSAPrivateKey(bp, &rsa, NULL, (void *)passwd);
if(rsa == NULL)
{
printf("open_private_key failed to PEM_read_bio_RSAPrivateKey!\n");
BIO_free(bp);
RSA_free(rsa); return NULL;
} printf("open_private_key success to PEM_read_bio_RSAPrivateKey!\n");
key = EVP_PKEY_new();
if(NULL == key)
{
printf("open_private_key EVP_PKEY_new failed\n");
RSA_free(rsa); return NULL;
} EVP_PKEY_assign_RSA(key, rsa);
return key;
} // 使用密钥加密,这种封装格式只适用公钥加密,私钥解密,这里key必须是公钥
int rsa_key_encrypt(EVP_PKEY *key, const unsigned char *orig_data, size_t orig_data_len,
unsigned char *enc_data, size_t &enc_data_len)
{
EVP_PKEY_CTX *ctx = NULL;
OpenSSL_add_all_ciphers(); ctx = EVP_PKEY_CTX_new(key, NULL);
if(NULL == ctx)
{
printf("ras_pubkey_encryptfailed to open ctx.\n");
EVP_PKEY_free(key);
return -1;
} if(EVP_PKEY_encrypt_init(ctx) <= 0)
{
printf("ras_pubkey_encryptfailed to EVP_PKEY_encrypt_init.\n");
EVP_PKEY_free(key);
return -1;
} if(EVP_PKEY_encrypt(ctx,
enc_data,
&enc_data_len,
orig_data,
orig_data_len) <= 0)
{
printf("ras_pubkey_encryptfailed to EVP_PKEY_encrypt.\n");
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(key); return -1;
} EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(key); return 0;
} // 使用密钥解密,这种封装格式只适用公钥加密,私钥解密,这里key必须是私钥
int rsa_key_decrypt(EVP_PKEY *key, const unsigned char *enc_data, size_t enc_data_len,
unsigned char *orig_data, size_t &orig_data_len, const unsigned char *passwd)
{
EVP_PKEY_CTX *ctx = NULL;
OpenSSL_add_all_ciphers(); ctx = EVP_PKEY_CTX_new(key, NULL);
if(NULL == ctx)
{
printf("ras_prikey_decryptfailed to open ctx.\n");
EVP_PKEY_free(key);
return -1;
} if(EVP_PKEY_decrypt_init(ctx) <= 0)
{
printf("ras_prikey_decryptfailed to EVP_PKEY_decrypt_init.\n");
EVP_PKEY_free(key);
return -1;
} if(EVP_PKEY_decrypt(ctx,
orig_data,
&orig_data_len,
enc_data,
enc_data_len) <= 0)
{
printf("ras_prikey_decryptfailed to EVP_PKEY_decrypt.\n");
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(key); return -1;
} EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(key);
return 0;
} int main()
{
char enc_text[512] = "";
char dec_text[512] = "";
size_t enc_len = 512;
size_t dec_len = 512;
//生成密钥对
generate_key_files("public.pem","private.pem",(const unsigned char*)"1234",4);
EVP_PKEY* pubkey = open_public_key("public.pem");
EVP_PKEY* prikey = open_private_key("private.pem",(const unsigned char *)"1234");
rsa_key_encrypt(pubkey,(const unsigned char*)"hello",6,(unsigned char*)enc_text,enc_len);
rsa_key_decrypt(prikey,(const unsigned char*)enc_text,enc_len,(unsigned char*)dec_text,dec_len,(const unsigned char *)"1234");
printf("%s\n",dec_text);
return 0;
}

四、运行结果

VS2010编译链接openssl静态库的更多相关文章

  1. 【转】Linux编译链接问题----静态库和动态库

    Linux静态库和动态库的命名规则 静态函数库 静态库的名字一般是libxxx.a,利用静态库编译生成的文件比较大,因为整个静态库所有的数据都会被整合进目标代码中. a) 优点: 编译后,可执行文件不 ...

  2. android ndk-build 编译静态库libxx.a 以及Android studio openssl 静态库配置(cmake)

    android ndk-build 编译静态库libxx.a 需求场景: 目前有安卓编码好的现在的openssl的两个.a,我们需要调用openssl的函数,并把功能再封装成.a; 这样使用时,在an ...

  3. 【转】iOS编译OpenSSL静态库(使用脚本自动编译)

    原文网址:https://www.jianshu.com/p/651513cab181 本篇文章为大家推荐两个脚本,用来iOS系统下编译OpenSSL通用库,如果想了解编译具体过程,请参看<iO ...

  4. NDK 链接第三方静态库的方法

    将NDK编译的第三方静态拷贝到JNI目录下,在Android.mk中添加如下代码 以openssl静态库(libcrypto-static.a)为例 第一种链接方法:LOCAL_LDFLAGS := ...

  5. iOS——为Xcode编译POCO C++静态库

    一.POCO C++ library简介 POCO C++ library是一个C++编写的跨平台库,主要实现网络连接.数据库管理以及服务器,适用于跨平台.嵌入式. 二.为Xcode编译POCO C+ ...

  6. Linux下编译、使用静态库和动态库 自己测过的

    每个程序实质上都会链接到一个或者多个的库.比如使用C函数的程序会链接到C运行时库,GUI程序会链接到窗口库等等.无论哪种情况,你都会要决定是链接到静态库(static libary)还是动态库(dyn ...

  7. android开发 NDK 编译和使用静态库、动态库 (转)

    在eclipse工程目录下建立一个jni的文件夹 在jni文件夹中建立Android.mk和Application.mk文件 Android.mk文件: Android提供的一种makefile文件, ...

  8. cmake的使用二:链接第三方静态库

    cmake的使用二:链接第三方静态库

  9. g++ 链接*.a静态库 方法

    g++在链接*.a静态库时,直接作为object使用,不需要使用-l ,但是需要注意调整顺序,被依赖的文件放在后面. 如: g++  -g  -o0 -Wno-deprecated  -I$(INCL ...

随机推荐

  1. [codevs 1306]广播操的游戏(Trie)

    题目:http://codevs.cn/problem/1306/ 分析:题意一看就知道就是要求Trie有多少个节点.但是如果每次单独取原串的所有子串加入Trie会超时,为什么呢?比方说AAABBBC ...

  2. 学习之路三十二:VS调试的简单技巧

    这段时间园子里讲了一些关于VS的快捷键以及一些配置技巧,挺好的,大家一起学习,一起进步. 这段时间重点看了一下关于VS调试技巧方面的书,在此记录一下学习的内容吧,主要还是一些比较浅显的知识. 1. 调 ...

  3. Bootstrap3.0学习第十二轮(导航、标签、面包屑导航)

    详情请查看http://aehyok.com/Blog/Detail/18.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:ht ...

  4. 每天一个linux命令(54):sftp命令

    sftp 是一个交互式文件传输程式.它类似于 ftp, 但它进行加密传输,比FTP有更高的安全性.下边就简单介绍一下如何远程连接主机,进行文件的上传和下载,以及一些相关操作. 举例,如远程主机的 IP ...

  5. Java Web技术总结(目录)

    来源于:http://www.jianshu.com/p/539bdb7d6cfa Java Web技术经验总结(一) Java Web技术经验总结(二) Java Web技术经验总结(三) Java ...

  6. myeclipse自动import

    不管包什么的 直接把代码全写出来 再按 ctrl + shift +o 这是自动导包的 前提是你写的代码是正确的

  7. struts的上传和下载

    上传: jsp: <body> <h1>filogin</h1> <!--如果表单中有文件文件控件,上传的编码必须是multipart/form-data - ...

  8. [转]SQL注入攻防入门详解

    原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============ ...

  9. Productivity Power Tools 动画演示--给力的插件工具

    免费的精品: Productivity Power Tools 动画演示 Productivity Power Tools 是微软官方推出的 Visual Studio 扩展,被用以提高开发人员生产率 ...

  10. Java设计模式-解释器模式(Interpreter)

    解释器模式是我们暂时的最后一讲,一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄. Context类是一个上下文环境类,Plus和Minus分别是用来计算的实现,代码如下: public ...