VS2010编译链接openssl静态库

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

一、环境配置

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

image

按照安装说明下载activeperl

二、编译静态库

执行命令:

cd D:openssl-1.0.1s 
D:
perl Configure VC-WIN32 no-asm --prefix=D:openssl-1.0.1s
msdo_ms

有类似输出

image

然后打开vs2010命令行工具

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

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

说明:

1.若想生成dll 则将ms t.mak 改为ms tdll.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.1sinc32

库目录添加

D:openssl-1.0.1sout32;

在项目--属性--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!
");
        return -1;
    }

    // 开始生成公钥文件
    BIO *bp = BIO_new(BIO_s_file());
    if(NULL == bp)
    {
        printf("generate_key bio file new error!
");
        return -1;
    }

    if(BIO_write_filename(bp, (void *)pub_keyfile) <= 0)
    {
        printf("BIO_write_filename error!
");
        return -1;
    }

    if(PEM_write_bio_RSAPublicKey(bp, rsa) != 1)
    {
        printf("PEM_write_bio_RSAPublicKey error!
");
        return -1;
    }

    // 公钥文件生成成功,释放资源
    printf("Create public key ok!
");
    BIO_free_all(bp);

    // 生成私钥文件
    bp = BIO_new_file(pri_keyfile, "w+");
    if(NULL == bp)
    {
        printf("generate_key bio file new error2!
");
        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!
");
        return -1;
    }

    // 释放资源
    printf("Create private key ok!
");
    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!
");
        return NULL;
    }

    rsa = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL);
    if(rsa == NULL)
    {
        printf("open_public_key failed to PEM_read_bio_RSAPublicKey!
");
        BIO_free(bp);
        RSA_free(rsa);

        return NULL;
    }

    printf("open_public_key success to PEM_read_bio_RSAPublicKey!
");
    key = EVP_PKEY_new();
    if(NULL == key)
    {
        printf("open_public_key EVP_PKEY_new failed
");
        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!
");

        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!
");
        BIO_free(bp);
        RSA_free(rsa);

        return NULL;
    }

    printf("open_private_key success to PEM_read_bio_RSAPrivateKey!
");
    key = EVP_PKEY_new();
    if(NULL == key)
    {
        printf("open_private_key EVP_PKEY_new failed
");
        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.
");
        EVP_PKEY_free(key);
        return -1;
    }

    if(EVP_PKEY_encrypt_init(ctx) <= 0)
    {
        printf("ras_pubkey_encryptfailed to EVP_PKEY_encrypt_init.
");
        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.
");
        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.
");
        EVP_PKEY_free(key);
        return -1;
    }

    if(EVP_PKEY_decrypt_init(ctx) <= 0)
    {
        printf("ras_prikey_decryptfailed to EVP_PKEY_decrypt_init.
");
        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.
");
        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
",dec_text);
    return 0;
}

四、运行结果

image

原文地址:https://www.cnblogs.com/Reyzal/p/5442159.html