OpenSSL编程环境搭建

一、需要的软件和环境

1)       OpenSSL(自行到官网下载最新版本openssl-1.0.2d.tar.gz!)

创新互联是一家专业从事成都网站制作、做网站的网络公司。作为专业网络公司,创新互联依托的技术实力、以及多年的网站运营经验,为您提供专业的成都网站建设、全网营销推广及网站设计开发服务!

2)       Perl(ActivePerl-5.12.2)

3)       Microsoft Visual Studio 2010(及以上版本)

二、安装步骤

1、正确安装和设置ActivePerl,Visual Studio 2010

常规方式安装好ActivePerl-5.12.2和Visual Studio 2010。

检验Perl是否安装成功的方法:

在windows命令行下运行如下命令:

1)       cd C:\Perl\eg (假定Perl的安装目录是C:\Perl);

2)       在该目录下执行:perl example.pl;

3)       若结果显示“Hello from ActivePerl!”,则说明Perl安装成功,可以开始使用Perl的相关命令来进行OpenSSL的安装了。

为Visual Studio 2010(VisualC++)设置临时环境变量

 

在命令行切换到VisualStudio 2010的安装目录下的VC子目录

1)       cd C:\Program Files\MicrosoftVisual Studio\VC (假定VisualStudio的安装目录为C:\ProgramFiles\Microsoft Visual Studio\);

2)       在命令行运行vcvarsall.BAT

注意:用这个命令来设置环境变量,其环境变量仅对当前的命令行窗口有效。

3)保留如图1窗口,切记不要关闭。

4)下载nasm-2.11.08-win32,解包后将两个可执行文件拷贝到VC的安装目录的子目录bin下。

2、正式开始安装OpenSSL

注意:因为为Visual Studio2010(Visual C++)设置的是临时环境变量,所以以下步骤所要执行的命令行命令必须是在步骤1的如图1的同一个命令行窗口下面执行。

 

(1)先将openssl软件包解压,并在命令行窗口中,切换到openssl解压后所在的主目录。

(2)执行Configure命令(该步骤的目的是配置编译参数,对编译环境进行基本的配置):

perl Configure VC-WIN32(注意该命令是大小写敏感的)

(3)执行如下命令(ms目录下的批处理命令do_ nasm生成makefile配置文件“ntdll.mak”):

ms\do_nasm

(4)执行如下命令(根据步骤(1)和(2)所生成的makefile文件“ntdll.mak”编译所有源代码):nmake -f ms\ntdll.mak

 其中可能出现各种错误,可以在百度或者www.aol.com上输入返回错误信息,以寻找到相应的处理措施。

(5) 对所有密码算法、SSL协议和相关功能进行测试:

nmake -f ms\ntdll.mak test

  如果出现以上提示("passedall tests")则说明成功。如果编译成功,最后的输出结果都在out32dll目录下:包括可执行文件、两个dll和两个lib文件: libeay32.dll,libeay32.lib,ssleay32.dll,ssleay32.lib,openssl.exe;

(6)将编译后的OpenSSL安装到缺省目录(如果上述的操作是在D:盘完成,则OpenSSL缺省按照到这个目录:D:\usr\local\ssl)nmake -f ms\ntdll.mak install

    把安装目录下的bin子目录和lib子目录的目录路径(例如D:\usr\local\ssl\bin和D:\usr\local\ssl\lib)添加到PATH环境变量中。

三、代码调试环境配置

VS-打开项目-项目-属性-VC++目录

OpenSSL编程环境搭建

更改包含目录以及库目录路径

OpenSSL编程环境搭建

注意包含目录只需要到include文件夹下即可,因为代码中openssl/evp.h已经包含了openssl文件夹。

OpenSSL编程环境搭建

然后在-连接器-输入中,将

OpenSSL编程环境搭建

文件夹下的两个库文件添加到附加依赖项

OpenSSL编程环境搭建

调试成功:

OpenSSL编程环境搭建

附调试代码:

/* -------------------------------------------------------------------------
*      Copyright (c) 2007     JianShen.
*                             All rights reserved.
*   This source code and any compilation or derivative thereof is the
*   proprietary information of Author(s). and is confidential in nature.
*
*   Under no circumstances is this software to be combined with any Open
*   Source Software in any way or placed under an Open Source License of
*   any type without the express written permission of  Author(s).
* ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
 *  Description:  
 *   	一个测试例子用于对消息进使用指定的算法进行加解密以及BASE64编码。
 *  Author: Jian Shen
 *  Created:2007/05/19
 *  Change History:
 * ------------------------------------------------------------------------- */
 #include 
 #include 
 #include 

//base64中每行的长度,最后一位是换行符号
#define CHARS_PER_LINE_BASE64 65  //64+1(\r)

void print(const char *promptStr,unsigned char *data,int len)
{
    int i;
    printf("======%s[长度=%d]======\n",promptStr,len);
    for(i = 0; i < len; i++) printf("%02x", data[i]);
    printf("\n===============\n");
}

//base64编码
void encode(unsigned char* outData,
            int * outlen,
            const unsigned char* data,
            int datalen)
{
    int tmp=0;
    EVP_ENCODE_CTX base64;
    EVP_EncodeInit(&base64);//base64编码初始化
    //编码数据,由于数据不多,所以没有使用循环
    EVP_EncodeUpdate(&base64,//base64编码上下文对象
        outData,//编码后的数据
        outlen, //编码后的数据长度
        data,   //要编码的数据
        datalen //要编码的数据长度
    );
    tmp=*outlen;
    //结束base64编码,事实上此时数据已经编码完全
    EVP_EncodeFinal(&base64,outData+*outlen,outlen);
    *outlen+=tmp;
    outData[*outlen]=0;
    print("base64编码后:",outData,*outlen);
}

//base64解码
bool decode(unsigned char* outData,
            int * outlen,
            const unsigned char* data,
            int datalen)
{
    int tmp=0,i=0,lines=0,currpos=0;
    EVP_ENCODE_CTX base64;
    EVP_DecodeInit(&base64);//base64解码初始化
	//假定outData缓冲区能够容纳所有的结果
    for (;;)
	{
        currpos+=CHARS_PER_LINE_BASE64*lines++;
		//下面函数的返回值中:i=1 表示还有更多行需要解码
		//i=0 表示没有进一步的数据需要解码
        i=EVP_DecodeUpdate(&base64,//base64解码上下文对象
            outData+tmp,     //解码后的数据
            outlen,          //解码后的数据长度
            data+currpos,    //要解码的数据
            datalen-currpos);//要解码的数据长度
	    if (i < 0)
        {
            printf("解码错误!\n");
            return false;
        }
        tmp+=*outlen;
        if (i == 0) break;//数据结束
    }
    //结束base64解码
    EVP_DecodeFinal(&base64,outData+tmp,outlen);
    *outlen=tmp;
    outData[*outlen]=0;
    print("base64解码后:",outData,*outlen);
    return true;
}

void main(int argc, char *argv[])
{
    const int ITERATIVE_ROUND_FOR_KEY=3;
    unsigned char key[EVP_MAX_KEY_LENGTH];//密钥
    unsigned char iv[EVP_MAX_IV_LENGTH];//初始向量
    EVP_CIPHER_CTX ctx;//加密上下文对象
    unsigned char out[512+8];
    int outl;
    unsigned char txtAfterDecrypt[512];
    int txtLenAfterDecrypt;

    char simpleText[]="Let's pray for peace of our lovely world";
    unsigned char txtAfterBase64[sizeof(simpleText)*3];

    //密码
    const char *passwd="a78b5C";//用于产生密钥的口令字符串
    const EVP_CIPHER *type;//加密类型对象
    OpenSSL_add_all_ciphers();//加载加密算法
    OpenSSL_add_all_digests();//加载摘要计算算法
    printf("密码是:%s\n",passwd);                                                                                                      
    type=EVP_des_ede3_cbc();                                                               
    printf("密钥长度=%d,向量长度=%d\n",type->key_len,type->iv_len);
	//从文本密码中产生 密钥/向量
    //这个例程使用MD5并且采用来自RSA的PCKS#5的标准
    EVP_BytesToKey(type,//密钥类型
        EVP_md5(),//摘要计算类型
        NULL,
        (const unsigned char *)passwd,//口令串
        (int)strlen(passwd),//口令串长度
        ITERATIVE_ROUND_FOR_KEY,//迭代轮数
        key,//输出的密钥
        iv  //输出的初始向量
        );
    //加密初始化,ctx是加密上下文对象
    EVP_EncryptInit(&ctx,type,key,iv);

    int tmp=(int)strlen(simpleText);
    //由于数据量少,不用循环加入数据
	EVP_EncryptUpdate(&ctx,//加密上下文对象
        out,//加密后的内容
        &outl, //加密后的内容长度
        (const unsigned char*)simpleText, //要加密的内容
        (int)strlen(simpleText)  //要加密的内容长度
        );
    tmp=outl;
    //结束加密
    EVP_EncryptFinal(&ctx,out+outl,&outl);
    outl+=tmp;
    //清除加密上下文,因为下文还要重用
    EVP_CIPHER_CTX_cleanup(&ctx);

    print("加密之后的结果:",out,outl);

    //进行base64编码
    encode(txtAfterBase64,&tmp,out,outl);
    memset(out,0,sizeof(out));
    //进行base64解码
    decode(out,&outl,txtAfterBase64,tmp);

	//解密初始化,解密类型,密钥,初始向量必需和加密时相同,否则解密不能成功
    EVP_DecryptInit(&ctx,type,key,iv);

	EVP_DecryptUpdate(&ctx,//解密上下文对象
        txtAfterDecrypt,   //解密后的内容
        &txtLenAfterDecrypt,//解密后的内容长度
        out,                //要解密的内容
        outl                //要解密的内容长度
        );
    tmp=txtLenAfterDecrypt;
    //结束解密
    EVP_DecryptFinal(&ctx,txtAfterDecrypt+txtLenAfterDecrypt,&txtLenAfterDecrypt);
    txtLenAfterDecrypt+=tmp;
    EVP_CIPHER_CTX_cleanup(&ctx);
    txtAfterDecrypt[txtLenAfterDecrypt]=0;

    printf("解密之后(长度=%d):\n[%s]\n\n",txtLenAfterDecrypt,txtAfterDecrypt);
    printf("click any key to continue.");
	//相当于暂停,观察运行结果
    getchar();
}



本文题目:OpenSSL编程环境搭建
当前URL:http://ybzwz.com/article/gipsed.html