本文探索Openssl的Engine机制.Openssl硬件引擎(Engine)能够使用户比较容易地将自己的硬件加入到openssl中去,替换其提供的软件算法.
ENGINE 是 OPENSSL 预留的用以加载第三方加密库引擎,主要包括了动态库加载的代码和加密函数指针管理的一系列接口.如果要使用 Engine(假设你已经加载上 该 Engine 了 ) , 那 么 首 先 要 加 载 该Engine(比如 ENGINE_load_XXXX),然后选择要使用的算法或者使用支持的所有加密算法。这样你的应用程序在调用加解密算法时,它就会指向你加载的动态库里的加解密算法,而不是原先的 OPENSSL的 库里的加解密算法.
使用Engine的基本流程:
①//Engine_load_xxxx();
初始化Engine对象,对engine的属性及方法进行设置(自己实现的算法),将engine加载到系统中,
②//e =Engine_by_id("ID_ali");
获取engine
③选择使用哪些算法
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传入方法即可.
EVP_EncryptInit_ex(ctx,ciper,e,key,iv);
这样便使用engine中的算法替换掉了SSL的自带算法.
说明:
a.ENGINE_load_hwcipher();这个方法进行Engine的初始化.
void ENGINE_load_hwcipher() { ENGINE *e_hw = engine_hwcipher(); if (!e_hw) return; ENGINE_add(e_hw); ENGINE_free(e_hw); ERR_clear_error(); }其中又调用engine_hwcipher()
static ENGINE *engine_hwcipher(void) { ENGINE *ret = ENGINE_new(); if (!ret) return NULL; if (!bind_helper(ret)) { ENGINE_free(ret); return NULL; } return ret; }
static int bind_helper(ENGINE *e) { int ret; ret = ENGINE_set_id(e, engine_hw_id); if (ret != 1) { printf("ENGINE_set_id failed\n"); return 0; } ret = ENGINE_set_name(e, engine_hw_name); if (ret != 1) { printf("ENGINE_set_name failed\n"); return 0; } ret = ENGINE_set_RSA(e, &hw_rsa); if (ret != 1) { printf("ENGINE_set_RSA failed\n"); return 0; } ret = ENGINE_set_RAND(e, &hw_rand); if (ret != 1) { printf("ENGINE_set_RAND failed\n"); return 0; } ret = ENGINE_set_destroy_function(e, hw_destroy); if (ret != 1) { printf("ENGINE_set_destroy_function failed\n"); return 0; } ret = ENGINE_set_init_function(e, hw_init); if (ret != 1) { printf("ENGINE_set_init_function failed\n"); return 0; } ret = ENGINE_set_finish_function(e, hw_finish); if (ret != 1) { printf("ENGINE_set_finish_function failed\n"); return 0; } ret = ENGINE_set_ctrl_function(e, hw_ctrl); if (ret != 1) { printf("ENGINE_set_ctrl_function failed\n"); return 0; } ret = ENGINE_set_load_privkey_function(e, hw_load_privkey); if (ret != 1) { printf("ENGINE_set_load_privkey_function failed\n"); return 0; } ret = ENGINE_set_load_pubkey_function(e, hw_load_pubkey); if (ret != 1) { printf("ENGINE_set_load_pubkey_function failed\n"); return 0; } ret = ENGINE_set_cmd_defns(e, hw_cmd_defns); if (ret != 1) { printf("ENGINE_set_cmd_defns failed\n"); return 0; } ret = ENGINE_set_ciphers(e, hw_ciphers); if (ret != 1) { printf("ENGINE_set_ciphers failed\n"); return 0; } ret = ENGINE_set_digests(e, hw_md); if (ret != 1) { printf("ENGINE_set_digests failed\n"); return 0; } return 1; }
b.至此,engine的初始化工作完成,然后 e = ENGINE_by_id("ID_hw");获取自己需要的engine.
c.选择要使用的算法.ENGINE_set_default(ENGINE *e, int Flag)
c.将engine传入加解密调用函数即可. EVP_EncryptInit_ex(&ciph_ctx, cipher, e, key, iv);
这样便实现了使用自定义算法替换openssl中默认算法.详细的代码可参考OpenSSL 源代码中的 Demos/Engines
原文地址:http://blog.csdn.net/leokelly001/article/details/44411255