VS2010编译链接openssl静态库

最近工作需要使用一些加密算法。之前尝试过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;
}

四、运行结果

时间: 2024-10-10 01:56:33

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

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

android ndk-build 编译静态库libxx.a 需求场景: 目前有安卓编码好的现在的openssl的两个.a,我们需要调用openssl的函数,并把功能再封装成.a; 这样使用时,在android studio jni项目 cmake 里面,需要先引用openssl的.a再引用 上面封装的.a; 如果使用so,那么,直接在android studio jni项目的 cpp里面直接调用openssl的方法,对外提供jni java接口,打包成so即可: 先来说用ndk-build 打

Windows下编译libcurl.lib静态库

1.下载最新版的libcurl,我的是curl-7.44.0.zip,解压,进入目录winbuild,仔细阅读BUILD.WINDOWS.txt这篇文档 打开VS2013 开发人员命令提示并执行nmake /f Makefile.vc mode=static VC=12 完成编译后libcurl静态库会出现在builds目录下包括头文件和libcurl_a.lib,我们需要的是builds/libcurl-vc12-x86-release-static-ipv6-sspi-winssl下面的in

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

一.POCO C++ library简介 POCO C++ library是一个C++编写的跨平台库,主要实现网络连接.数据库管理以及服务器,适用于跨平台.嵌入式. 二.为Xcode编译POCO C++ 静态库 1.确定需要编译的版本 要想使POCO C++在iOS的各个平台上运行,那么需要针对各个平台的不同架构进行编译,因此我们需要了解iOS各个平台的架构,主要分为iPhone模拟器.iPhone真机以及运行Xcode电脑本身的架构. (1)iPhone模拟器 目前iPhone模拟器架构分为两

g++编译使用生成静态库和动态库(Linux)

参考文献: Linux下g++编译与使用静态库和动态库 用g++编译生成动态链接库*.so的方法及连接(多个.cc生成一个*.so) 占坑

编译 python 生成静态库 libpython2.7.so

由于我们是C++作驱动的Python开发,驱动需要加上Python静态库libpython2.7.so.libpython2.7.so.1.0.libpython2.7.a.此处我想在python源码上加上自己加的log,因此要重新编译Python生成静态库,再生成驱动. 一般快速编译安装Python源码步骤: ./configure make make install 如果要生成静态库libpython2.7.so.libpython2.7.so.1.0.libpython2.7.a,则为:

VS2013编译Qt5.4静态库

设置了一天,这静态编译也总算是虐出来了...Qt 的静态编译简直不要太麻烦啊... 感谢这位大神提供的方法 http://zerooverture.com/tutorials/qt/737.html 工具下载: http://pan.baidu.com/s/1hq2Cff2 一.环境配置 我目前用的系统是Windows 7 64bit,请注意安装好以下软件,以及配置好环境变量: Visual Studio 2013 python perl 安装好以上软件 请用cmd测试下 python和perl

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

在eclipse工程目录下建立一个jni的文件夹 在jni文件夹中建立Android.mk和Application.mk文件 Android.mk文件: Android提供的一种makefile文件,用来指定诸如编译生成so库名.引用的头文件目录.需要编译的.c/.cpp文件和.a静态库文件等.详见附件中的Android.mk. Application.mk文件: 定义了项目的一些细节,比如APP_ABI := x86(编译X86平台库).APP_PLATFORM := android-9(使用

android开发 NDK 编译和使用静态库、动态库

在eclipse工程目录下建立一个jni的文件夹. 在jni文件夹中建立Android.mk和Application.mk文件. Android.mk文件: Android提供的一种makefile文件,用来指定诸如编译生成so库名.引用的头文件目录.需要编译的.c/.cpp文件和.a静态库文件等.详见附件中的Android.mk. Application.mk文件: 定义了项目的一些细节,比如APP_ABI := x86(编译X86平台库).APP_PLATFORM := android-9(

vs2010 链接OpenCV 静态库

1. 添加opencv 头文件路径 Properties-> VC++ Directories -> Include Directories += $(OPENCV_INC) 2. runtime library 由dll改为非dll Properties-> c/c++ / Code Generation -> Runtime Library     =   /MT   (默认是/MD ) 3. 添加opencv 库路径 Properties-> Linker->Ge