OPENSSL ENGINE机制

  • Post author:
  • Post category:其他





1.





概念









OpenSSL



项目




是一个开放源代码安全项目,它的目标是开发一个健壮的、商业级的、完整的开放源代码的工具包,用强大的加密算法来实现安全的



Socket



层(



Secure Sockets Layer







SSL v2/v3



)和传输层的安全性(



Transport Layer Security







TLS v1



)。它包含了完整的加密算法,数字签名算法及证书算法等。可以很好地保证数据的完整,保密和正确性。



OpenSSL



可以和于商业用途,但是使用者应该考虑自己所使用的算法有没有受到本国专利的限制以及考虑是否符合国家制定的标准。









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



接口支持不一定很全面,比如,可能支持其中一两种公开密钥算法。表



1







OpenSSL-0.9.7



版本支持的硬件及其对应的简要描述名称,这个简要描述名称在很多时候是要使用的,如编程或执行命令的时候,简要密钥名称是大小写敏感的,目前一般都是采用小写字符。




OpenSSL



支持的



Engine



接口






简要名称






Engine



接口描述





dynamic


动态加载


Engine


设备的接口





cswift


CryptoSwift


的硬件加密设备


Engine


支持





chil


nChipher


硬件加密设备


Engine


支持





atalla


Atalla


硬件加密设备


Engine


支持





nuron


Nuron


硬件加密设备


Engine


支持





ubsec


UBSEC


硬件加密设备


Engine


支持





aep


Aep


硬件加密设备


Engine


支持





sureware


SureWare


硬件加密设备


Engine


支持





4758cca


IBM 4758 CCA


硬件加密设备


Engine


支持













2.





实现








ENGINE





OPENSSL

预留的用以加载第三方加密库引擎,主要包括了动态库加载的代码和加密函数指针管理的一系列接口。如果要使用

Engine

(假设你已经加载上该

Engine

了),那么首先要加载该

Engine(

比如

ENGINE_load_XXXX)

,然后选择要使用的算法或者使用支持的所有加密算法(有相关函数)。这样你的应用程序在调用加解密算法时,它就会指向你加载的动态库里的加解密算法,而不是原先的

OPENSSL


的库里的加解密算法。



上面提到的一些


engine

的实现在

openssl/crypto/engine/


目录下可以找到,来分析一下具体的实现:



首先,每一个


ENGINE_load_XXXX


其实就是一个


Engine

的加载过程:







如:






void



ENGINE_load_rtl8651b(void)



{





ENGINE *engine = ENGINE_new();





if (engine == NULL)





return;





if (!ENGINE_set_id(engine, “rtl8651b”) ||





!ENGINE_set_name(engine, “BSD rtl8651b engine”) ||





!ENGINE_set_ciphers(engine, rtl8651b_engine_ciphers)||





!ENGINE_set_digests(engine, rtl8651b_engine_digests)||





!ENGINE_set_ctrl_function(engine, rtl8651b_ctrl) ||






!ENGINE_set_cmd_defns(engine, rtl8651b_defns)






){








ENGINE_free(engine);





return;





}








if(!ENGINE_set_default(engine, ENGINE_METHOD_DIGESTS) )








ENGINE_add(engine);





ENGINE_free(engine);






ERR_clear_error();



}



类似


ENGINE_set_xxxx

的函数是对

engine


机制各个方面的设定注册,有下面这些:



int ENGINE_set_id(ENGINE *e, const char *id);



int ENGINE_set_name(ENGINE *e, const char *name);






int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);



int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);



int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);



int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);






int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);



int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);



int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);



int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);



int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);



int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);






int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);



int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);






int ENGINE_set_flags(ENGINE *e, int flags);



int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);








由此可知,具体的(



RSA







DSA







DH







RAND







CHIPHERS







DIGESTS



)算法实现主要是这些函数实现的。








DIGESTS

为例:首先要声明一个对应的数据结构(

MD5

):



const EVP_MD rtl8651b_hash_md5={





NID_md5,





NID_md5WithRSAEncryption,






MD5_DIGEST_LENGTH,






NULL,





rtl8651b_digest_init,





rtl8651b_digest_update,







rtl8651b_digest_final,





NULL,







NULL,





EVP_PKEY_RSA_method,





MD5_CBLOCK,





sizeof(RTL_DIGEST_CTX)/* how big does the ctx->md_data need to be */





};







具体的各项的含义,请参考


EVP_MD


数据结构。






这里


rtl8651b_digest_init, rtl8651b_digest_update, rtl8651b_digest_final,


就是具体的算法实现。









如果都完成了,则可以


调用动态库中的


ENGINE_load_XXXX(


例子中是


ENGINE_load_ rtl8651b)








ENGINE


对象加载到系统中





即在


ENGINE


对象和


DIGESTS


的结构里的


ENGINE


对象建立了一个关联





使用这种方法





使


ENGINE


能够智能的判断是使用自定义的加解密算法





还是使用默认的加解密算法。


ENGINE_load_ rtl8651b


中,我们可以


使用下面的方法来使用你所定义的算法。





ENGINE_set_default(ENGINE *e, int Flag)


其中


Flag

的说明如下:





ENGINE_METHOD_ALL


使用所有存在的算法


(

默认

)





ENGINE_METHOD_RSA


仅使用


RSA

算法






ENGINE_METHOD_DSA


仅使用


DSA

算法






ENGINE_METHOD_DH


仅使用


DH


算法



ENGINE_METHOD_RAND


仅使用随机数算法







ENGINE_METHOD_CIPHERS


仅使用对称加解密算法







ENGINE_METHOD_DIGESTS


仅使用摘要算法






ENGINE_set_default(engine, ENGINE_METHOD_DIGESTS)









上面给出使用


ENGINE

有效替换

OPENSSL

中现有的所有的加密算法,使用这个特性也可以很好的加入一些

OPENSSL


中所没有的加解密算法,这使开发加解密算法的应用程序更加简便,相对于传统的开发方法是一个有效稳妥的方法。









From:

http://www.cnblogs.com/adylee/archive/2008/03/19/1113620.html