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
接口
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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