Engine机制 Engine机制的出现是在OpenSSL的0.9.6版的事情,开始的时候是将普通版本跟支持Engine的版本分开的,到了OpenSSL的0.9.7版,Engine机制集成到了OpenSSL的内核中,成为了OpenSSL不可缺少的一部分。 Engine机制目的是为了使OpenSSL能够透明地使用第三方提供的软件加密库或者硬件加密设备进行加密。OpenSSL的Engine机制成功地达到了这个目的,这使得OpenSSL已经不仅仅使一个加密库,而是提供了一个通用地加密接口,能够与绝大部分加密库或者加密设备协调工作。当然,要使特定加密库或加密设备更OpenSSL协调工作,需要写少量的接口代码,但是这样的工作量并不大,虽然还是需要一点密码学的知识。Engine机制的功能跟Windows提供的CSP功能目标是基本相同的。目前,OpenSSL的0.9.7版本支持的内嵌第三方加密设备有8种,包括:CryptoSwift、nCipher、Atalla、Nuron、UBSEC、Aep、SureWare以及IBM 4758 CCA的硬件加密设备。现在还出现了支持PKCS#11接口的Engine接口,支持微软CryptoAPI的接口也有人进行开发。当然,所有上述Engine接口支持不一定很全面,比如,可能支持其中一两种公开密钥算法。
我们来实现基于VC++的openssl engine编程,请见代码实现与注释讲解
#include "commonlib.h" #include "simple_engine_def.h" #include <openssl/evp.h> int main() { ENGINE *e; const EVP_CIPHER *cipher=EVP_des_ecb(); EVP_CIPHER_CTX ciph_ctx; unsigned char key[16],iv[16]; const char* info="this is a simple engine test"; unsigned char out[100],dec_data[100]; int outl,total; OpenSSL_add_all_algorithms(); ENGINE_load_simplecipher();//加载自定义的engine e=ENGINE_by_id(SIMPLE_ENGINE_ID); printf("Engine 名称 :%s \n",(char *)ENGINE_get_name(e)); //随机数生成 if( RAND_set_rand_engine(e)==0 ) int_error("RAND_set_rand_engine 错误\n"); //利用自定义随机数算法生成随机数并填充到key中用于加解密 RAND_bytes(key,sizeof(key)); printf("生成的随机数字符串为:"); for(int i = 0; i < sizeof(key); i++) printf("%c", key[i]); printf("\n"); //对称加密 EVP_CIPHER_CTX_init(&ciph_ctx); //采用Engine对称算法 if( EVP_EncryptInit_ex(&ciph_ctx,cipher,e,key,iv)==0 ) int_error("EVP_EncryptInit_ex 错误\n"); total=0; if( EVP_EncryptUpdate(&ciph_ctx,out,&outl,(const unsigned char*)info,(int)strlen(info))==0 ) int_error("EVP_EncryptUpdate 错误\n"); total+=outl; if( EVP_EncryptFinal(&ciph_ctx,out+total,&outl)==0 ) int_error("EVP_EncryptFinal 错误\n"); total+=outl; printf("加密后的数据为:\n"); for( int j = 0; j < total; j++) printf("%02x", out[j]); printf("\n"); //解密 if( EVP_DecryptInit_ex(&ciph_ctx,cipher,e,key,iv)==0 ) int_error("EVP_DecryptInit_ex 错误\n"); if( EVP_DecryptUpdate(&ciph_ctx,dec_data,&outl,out,total)==0 ) int_error("EVP_DecryptUpdate 错误\n"); total=outl; if( EVP_DecryptFinal(&ciph_ctx,dec_data+total,&outl)==0 ) int_error("EVP_DecryptFinal 错误"); total+=outl; dec_data[total]=0; printf("解密之后内容(长度=%d):[%s]\n",total,dec_data); return 0; }