zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    如何使用pip安装PythonMySQLdb模块?
    Linux:信号(1):signal函数、pause函数、alarm函数
    python字符串前面加上'r'的作用
    在LINUX中 用Ctrl+z挂起的命令怎么切回到原任务的命令窗口
    A*寻路初探 GameDev.net
    [3d跑酷] Xcode5 打包 发布配置
    [cb]NGUI组件基类之 UIWidget
    [cb]Unity 项目架构
    使用Unity3D的50个技巧:Unity3D最佳实践
    Doxygen Tool For Unity
  • 原文地址:https://www.cnblogs.com/Reyzal/p/5442159.html
Copyright © 2011-2022 走看看