一:ENGINE的目的:
ENGINE是OPENSSL预留的加载第三方加密库,主要包括了动态库加载的代码和加密函数指针管理的一系列接口。如果要使用Engine(假设你已经加载上该Engine了),那么首先要Load该Engine(比如ENGINE_load_XXXX),然后选择要使用的算法或者使用支持的所有加密算法(有相关函数)。这样你的应用程序在调用加解密算法时,它就会指向你加载的动态库里的加解密算法,而不是原先的OPENSSL的libeay32.dll库里的加解密算法。
二:ENGINE原理:
使用你自己编译的加解密动态库里的函数的指针或硬件接口指针来替换OPENSSL
中默认的加解密函数,类似于HOOK,这样实现动态加载第三方密码库;
三:ENGINE操作流程:
例如替换RSA:
NO.1声明你要替换的函数名称和其它内部使用的函数
NO.2声明RSA_Method结构,要替换的函数就提供函数名,不提换就是NULL
了,还有其它的类型也要填上;
NO.3利用Engine_init等一系列函数初始化ENGINE库(其实上就是在初始化加
解密算法),主要是绑定特定的函数指针(自定义)和结构或初始化硬件设备等等操作;
Engine_finish也是一样,做一些清理工作;
NO.4实现真正的接口,包括RSA密钥结构的转换,如果是不能取出的私钥,要
保存硬件设备提供的指针(通常是HANDLE)等等操作。然后调用硬件的加密解密函数。
四:程序实例:(实现ENGINE)
NO.1声明函数名称
static int rsaref_private_decrypt(int len, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
NO.2声明RSA_Method结构
static RSA_METHOD rsaref_rsa =
{
"RSAref PKCS#1 RSA",
NULL;
NULL;
rsaref_private_encrypt,
NULL;
NULL;
NULL;
NULL,
NULL,
0,
NULL,
NULL,
NULL
};
NO.3代码实现
static int rsaref_private_decrypt(int len, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
//真实代码
}
NO.4初始化ENGINE
static int bind_rsaref(ENGINE *e)
{
if(!ENGINE_set_id(e, engine_rsaref_id)
|| !ENGINE_set_name(e, engine_rsaref_name)
|| !ENGINE_set_RSA(e, &rsaref_rsa)
)
return 0;
return 1;
}
int bind_helper(ENGINE *e, const char *id)
{
if(id && (strcmp(id, engine_rsaref_id) != 0))
return 0;
if(!bind_rsaref(e))
return 0;
return 1;
}
__declspec( dllexport ) void ENGINE_load_rsaref(void)
{
ENGINE *toadd = engine_rsaref();
if(!toadd)
return;
ENGINE_add(toadd);
}
五:操作ENGINE(使用ENGINE)
NO.1加载ENGINE
一般是调用动态库中的ENGINE_load_XXXX(例子中是ENGINE_load_rsare),把ENGINE对象加载到系统中,其实就是在ENGINE对象和RSA的结构里了ENGINE对象(参见RSA结构中的ENGINE定义)建立了一个关联,这样在用到RSA算法时如果RSA中的ENGINE对象为NULL,则调用默认的加解密算法,否则调用ENGINE对象里的加解密算法。
NO.2指定你所需要的ENGINE
应用程序中可能要用到不只一个ENGINE接口,它们按链表的形式组织在一起,
这样你就需要指定你需要的ENGINE接口;例:ENGINE*e = ENGINE_by_id("rsaref");
返回的ENGINE对象里就指向你自定义的加解密接口。
NO.3选择算法
ENGINE_set_default(ENGINE *e, int Flag)
Flag Description
ENGINE_METHOD_ALL使用所有存在的算法(默认)
ENGINE_METHOD_RSA仅使用RSA算法
ENGINE_METHOD_DSA仅使用DSA算法
ENGINE_METHOD_DH仅使用DH算法
ENGINE_METHOD_RAND仅使用随机数算法
ENGINE_METHOD_CIPHERS仅使用对称加解密算法
ENGINE_METHOD_DIGESTS仅使用摘要算法
NO.4使用加解密算法
使用ENGINE替换了算法后不影响原用或现用所有对加解密函数的调用操作。
源码下载