openssl engine实现和原理

OPENSSL ENGINE概述

能够使用户比较容易地将自己的硬件加入到openssl中去,替换其提供的软件算法。一个Engine提供了密码计算中各种计算方法的集合,它用于控制openssl的各种密码计算。

OPENSSL ENGINE实现:

OPENSSL ENGINE替换第三方算法方法:OPENSSL算法库中每一个算法对应一个唯一的NID,第三方算法绑定已有的NID,OPENSSL加密库算法的函数指针就会被第三方软件加密库的函数指针或硬件加密模块的接口指针替换掉

  1. 向OPENSSL协议库中注册第三方算法

加载引擎后可以使用新注册的算法(注册NID),对OPENSSL加密库中原有的算法的使用不影响,缺点需要修改源码,相对麻烦。

  1. 第三方算法替换OPENSSL协议库指定原算法

第三方加密算法通过绑定算法NID,替换OPENSSL加密库同NID算法,加载引擎后OPENSSL加密库中被换掉的算法将无法使用,无需修改 OpenSSL 源代码,实现容易,也经常被采用。

下面通过第二种方法实现ENGINE

ENGINE实现通过init、finis、destory三个函数在bind函数中体现

  1. 下面以RSA为例

/*rsa_engine.c文件*/
#include "rsa_engine.h"
#include <stdio.h>
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
static const char *engine_id="RSA123"; //engine id
static const char *engine_name="RSA enging support"; //engine name
static int rsa_sign(int type,const unsigned char *m, unsigned int m_length,unsigned char *sigret, unsigned int *siglen,const RSA *rsa)
{
printf("rsa_sign \n");
    return 1;
}
static int rsa_verify (int dtype, const unsigned char *m,unsigned int m_length, const unsigned char *sigbuf,unsigned int siglen, const RSA *rsa)
{
printf("rsa_verify \n");
    return 1;
}
static int rsa_pub_enc(int flen, const unsigned char *from,unsigned char *to, RSA *rsa, int padding)
{   
    printf("**************rsa_pub_enc, my function called, success!***********\n");
    return 1;
}
static int rsa_pub_dec(int flen, const unsigned char *from,unsigned char *to, RSA *rsa, int padding)
{   
    printf("**************rsa_pub_dec, my function called, success!***********\n");
    return 1;
}
//初始化 RSA方法的结构体
static RSA_METHOD rsa_pp =
{
    "RSA eg",
    rsa_pub_enc,
    rsa_pub_dec,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    0,
    NULL,
    rsa_sign,
    rsa_verify,
NULL
};
//初始化
static int rsa_init(ENGINE *e)
{
    printf("rsa engine init\n");
    return 1;
}
static int rsa_finish(ENGINE *e)
{
    printf("rsa engine finish\n");
    return 1;
}
//回收
static int rsa_destory(ENGINE *e)
{
    printf("rsa engine destory\n");
    return 1;
}
//注册函数
static int bind_pp(ENGINE *e)
{
    if(!ENGINE_set_id(e,engine_id)||
    !ENGINE_set_name(e,engine_name)||   
    !ENGINE_set_RSA(e,&rsa_pp)||
    !ENGINE_set_destroy_function(e,rsa_destory)||
    !ENGINE_set_init_function(e,rsa_init)||
    !ENGINE_set_finish_function(e,rsa_finish))
        return 0;
    printf("ERR_load_rsa success\n");
    return 1;
}
static int bind_helper(ENGINE *e, const char *id)
{
if(id && (strcmp(id, engine_id) != 0))
return 0;
if(!bind_pp(e))
return 0;
return 1;
}  
//通过ENGINE_load_XX方式通过动态方式调用
#ifdef ENGINE_DYNAMIC_SUPPORT 
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
#else
static ENGINE *engine_rsa(void)
{
    ENGINE *ret = ENGINE_new();
if(!ret)
return NULL;
if(!bind_pp(ret))
{
ENGINE_free(ret);
return NULL;
}
return ret;
}
void ENGINE_load_rsapp(void)
{
ENGINE *rsa_st = engine_rsa();
if(!rsa_st) 
        return;
ENGINE_add(rsa_st);
ENGINE_free(rsa_st);
ERR_clear_error();
}
#endif
#if 1
int main()
{
  ENGINE_load_rsapp(); //加载引擎
  ENGINE *rsa_st = NULL;
  rsa_st = ENGINE_by_id("RSA123"); //通过id返回ENGINE对象
if(rsa_st == NULL)
{
printf("get pkcs11 engine Error\n");
return 0;
}
  printf("name:%s\n",ENGINE_get_name(rsa_st));
  int  inl,outl,total,dtotal;
  RSA             *rkey;
  RSA_METHOD       *rsa_m;
  EVP_PKEY     *ek,*pkey;
  rkey=RSA_new_method(rsa_st);
  printf("rkey:%s\n",rkey);
  pkey=EVP_PKEY_new();
  EVP_PKEY_set1_RSA(pkey,rkey);
  ENGINE_register_RSA(rsa_st); //
  ENGINE_set_default(rsa_st,ENGINE_METHOD_RSA);
  unsigned char from[128]="aaaaaaaaa";
  unsigned char out[1024]={0};
  RSA_public_encrypt(sizeof(from),from,out,rkey,1);
  printf("crt:%s\n",out);
  RSA_public_decrypt(sizeof(out),out,from,rkey,1);
  printf("crt:%s\n",from);
  rv = ENGINE_finish(rsa_st);
  printf("test end.\n");
}
#endif
/*rsa_engine.h*/
#ifndef rsa_engine_H
#define rsa_engine_H
#include <openssl/engine.h>
struct rsa_meth_st {
    char *name;
    int (*rsa_pub_enc) (int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);
    int (*rsa_pub_dec) (int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);
    int (*rsa_priv_enc) (int flen, const unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);
    int (*rsa_priv_dec) (int flen, const unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);
    /* Can be null */
    int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
    /* Can be null */
    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
    /* called at new */
    int (*init) (RSA *rsa);
    /* called at free */
    int (*finish) (RSA *rsa);
    /* RSA_METHOD_FLAG_* things */
    int flags;
    /* may be needed! */
    char *app_data;
    /*
     * New sign and verify functions: some libraries don't allow arbitrary
     * data to be signed/verified: this allows them to be used. Note: for
     * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
     * *NOT* be used RSA_sign(), RSA_verify() should be used instead.
     */
    int (*rsa_sign) (int type,
                     const unsigned char *m, unsigned int m_length,
                     unsigned char *sigret, unsigned int *siglen,
                     const RSA *rsa);
    int (*rsa_verify) (int dtype, const unsigned char *m,
                       unsigned int m_length, const unsigned char *sigbuf,
                       unsigned int siglen, const RSA *rsa);
    /*
     * If this callback is NULL, the builtin software RSA key-gen will be
     * used. This is for behavioural compatibility whilst the code gets
     * rewired, but one day it would be nice to assume there are no such
     * things as "builtin software" implementations.
     */
    int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
    int (*rsa_multi_prime_keygen) (RSA *rsa, int bits, int primes,
                                   BIGNUM *e, BN_GENCB *cb);
};

void ENGINE_load_rsapp(void);
#endif // DEBUG
编译
gcc rsa_engine.c -lssl -lcrypto
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值