当前位置:编程学习 > VC++ >>

VC++网络安全编程范例(9)-基于OPENSSL实现对称算法与BASE64编码

 

“我的2011”博客频道跨年征文活动火爆上线!                                           正在写年终总结?速度参加CSDN“我的2011”征文大赛

下载频道领任务赚下载分活动开始啦!!!                                                          点击了解英特尔云计算

VC++网络安全编程范例(9)-基于OPENSSL实现对称算法与BASE64编码

分类:VC++编程技术Visual C++2010编程技术Visual Studio2012 Windows8 信息安全2011-12-17 13:31 126人阅读 评论(0) 收藏 举报

 

对称密码算法有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,反过来也成立。在大多数对称算法中,加密解密密钥是相同的。这些算法也叫秘密密钥算法或单密钥算法,它要求发送者和接收者在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都能对消息进行加密解密。只要通信需要保密,密钥就必须保密。

 

 

 

对称算法的加密和解密表示为:

 

  Ek(M)=C

 

  Dk(C)=M

 

  对称算法可分为两类。一次只对明文中的单个位(有时对字节)运算的算法称为序列算法或序列密码。另一类算法是对明文的一组位进行运算,这些位组称为分组,相应的算法称为分组算法或分组密码。现代计算机密码算法的典型分组长度为64位――这个长度大到足以防止分析破译,但又小到足以方便作用。

 

  这种算法具有如下的特性:

 

  Dk(Ek(M))=M

 

  常用的采用对称密码术的加密方案有5个组成部分(如图所示)

 

  l)明文:原始信息。

 

  2)加密算法:以密钥为参数,对明文进行多种置换和转换的规则和步骤,变换结果为密文。

 

  3)密钥:加密与解密算法的参数,直接影响对明文进行变换的结果。

 

  4)密文:对明文进行变换的结果。

 

  5)解密算法:加密算法的逆变换,以密文为输入、密钥为参数,变换结果为明文。

 

 

 

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。

 

 

 

 

请见代码实现案例

 

 #include <stdio.h>  

 #include <string.h>  

 #include <openssl/evp.h>  

 

//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 //要编码的数据长度   www.zzzyk.com

    ); 

    tmp=*outlen; 

    //结束base64编码,事实上此时数据已经编码完全  

    EVP_EncodeFinal(&base64,outData+*outlen,outlen); 

    *outlen+=tmp; 

    outData[*outlen]=0; 

    printf("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; 

补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,