一: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替換了算法後不影響原用或現用所有對加解密函數的調用操作。
源碼下載