Openssl中有AES、DES、Blowfish、CAST、IDEA、RC2、RC5等对称算法的实现函数,而且有一个统一的编程接口,很方便应用,但难于理解,当然你也可以自己去写Openssl的扩展函数,这样就更加方便了。这里我想用DES 算法来举例说说Openssl编程的一般流程。以下是VC环境里调试成功的程序,可以直接运行。
在运行程序之前你必须做好前期准备,否则无法调试,这里我们要用到Openssl的EVP,我们需要在工程中引入要用到的链接库文件libeay32.lib,(创建好一个工程后Project->Settings->Link在Object/Library Moduls:中添加libeay32.lib,并且要保证libeay32.dll已经放在了System32目录下了),这些都完成后你就可以直接运行程序了。
/***********************Des Code****************/
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
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");
}
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[]="这是一个Openssl测试程序,采用对称算法:des_ede3_cbc.";
//密码
const char *passwd="a78b5C";//用于产生密钥的口令字符串
const EVP_CIPHER *type;//加密类型对象
OpenSSL_add_all_ciphers();//加载加密算法
OpenSSL_add_all_digests();//加载摘要计算算法
printf("密码是:%s\n",passwd);
printf("原文:%s\n",simpleText);
type=EVP_des_ede3_cbc(); //这里可以选择算法类型
//从文本密码中产生 密钥/向量
//这个例程使用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);
//解密初始化,解密类型,密钥,初始向量必需和加密时相同,否则解密不能成功
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",txtLenAfterDecrypt,txtAfterDecrypt);
getchar();
}
代码有点乱,但条理很清晰,从上面的代码中我们很容易就可以知道它的基本流程了。
首先得有个初始化的过程OpenSSL_add_all_ciphers();OpenSSL_add_all_digests();加载加密算法,加载摘要计算算法,这个程序中我们其实运用了两个算法,加密和摘要。在生成密钥的时候用到了MD5,所以我们要事先声明下,BytesToKey()函数将我们的口令转换成程序可以识别的密钥。然后就要初始化加密上下文对象CTX, 加解密初始化功能 EVP_EncryptInit(&ctx,type,key,iv); 加解密更新函数EVP_EncryptUpdate()结束加解密函数 EVP_EncryptFinal(&ctx,out+outl,&outl);然后解密的过程是一样的就是把Encrypt换成Decrypt。
当然这个程序只是简单的测试而已。有兴趣的同仁可以讨论一下,我现在在学习Openssl