openssl engine实现和原理

这篇具有很好参考价值的文章主要介绍了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为例文章来源地址https://www.toymoban.com/news/detail-664756.html

/*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

到了这里,关于openssl engine实现和原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++中的网络编程和安全性:实现安全的Web应用程序和网络应用程序

    作者:禅与计算机程序设计艺术 《67. C++中的网络编程和安全性:实现安全的Web应用程序和网络应用程序》 1.1. 背景介绍 随着互联网的快速发展,网络应用程序在人们的生活和工作中扮演着越来越重要的角色,网络编程和安全性也成为了现代应用程序的重要组成部分。在网络

    2024年02月16日
    浏览(51)
  • 网络协议安全:ARP欺骗原理解析,arpspoof实现ARP欺骗,ARP欺骗防御。

    「作者简介」: 2022年北京冬奥会中国代表队,CSDN Top100,学习更多干货,请关注专栏《网络安全自学教程》 ARP是 「无状态协议」 ,不需要请求就能响应。比如我 「伪造」 一个 「ARP响应」 ,你收到以后就会把我响应的 「映射关系」 保存到你的 「ARP缓存表」 里。如果我把

    2024年04月17日
    浏览(37)
  • 【网络安全】【密码学】【北京航空航天大学】实验五、古典密码(中)【C语言实现】

    实验目的 和 原理简介 参见博客:古典密码(上) 1、弗纳姆密码(Vernam Cipher) (1)、算法原理 加密 原理: 加密过程可以用方程 ci = pi (+) ki 表示,其中 pi 是明文第 i 个二进制位, ki 是密钥第 i 个二进制位, ci 是密文第 i 个二进制位, (+) 是 异或 运算符。密文是通过对明

    2024年01月21日
    浏览(63)
  • 【网络安全】【密码学】【北京航空航天大学】实验三、数论基础(下)【C语言实现】

    1、中国剩余定理(Chinese Remainder Theorem) (1)、算法原理 m1 , m2 , … mk 是一组 两两互素 的正整数,且 M = m1 · m2 · … · mk 为它们的乘积, 则如下的同余方程组: x == a1 (mod m1) x == a2 (mod m2) … x == ak (mod mk) 对于 模M 有唯一的解 x = (M · e1 · a1 / m1 + M · e2 · a2 / m2 + … + M · ek ·

    2024年02月02日
    浏览(47)
  • 【网络安全】【密码学】【北京航空航天大学】实验四、古典密码(上)【C语言实现】

    1、 通过本次实验,了解古典加密算法的 主要思想 ,掌握 常见的 古典密码。 2、 学会 应用 古典密码,掌握针对部分古典密码的 破译方法 。 古典密码的编码方法主要有两种: 置换 和 代替 。 置换密码 重新排列明文中字符的顺序,不改变字符本身; 代替密码 不改变明文中

    2024年01月21日
    浏览(66)
  • 【网络安全】【密码学】【北京航空航天大学】实验一、数论基础(上)【C语言和Java实现】

    1、通过本次实验,熟悉相关的编程环境,为后续的实验做好铺垫; 2、回顾数论学科中的重要基本算法,并加深对其的理解,为本学期密码学理论及实验课程打下良好的基础。 数论主要研究的是整数的运算及性质,许多常用的加密算法都用到了数论知识。 本次实验的实验环

    2024年01月25日
    浏览(55)
  • 【网络安全】【密码学】【北京航空航天大学】实验二、数论基础(中)【C语言和Java实现】

    1、扩展欧几里得算法(Extended Euclid’s Algorithm) (1)、算法原理 已知整数 a , b ,扩展的欧几里得算法可以在求得 a , b 的 最大公约数 的同时,找到一对整数 x , y ,使得 a , b , x , y 满足如下等式: ax + by = d = gcd(a,b) , 其中 gcd(a, b) 为 a 和 b 的最大公约数。 (2)、算法流程 本算

    2024年02月01日
    浏览(55)
  • 网络安全实验——web安全

    目录 实验目的 实验原理 实验内容 实验1 1. 地址栏中执行脚本 2. 对DOM技术的利用 实验2  1.jump1 2.jump2 3.get 4.xss 5.注册bss 6.盗取cookie 7.分析cookie  实验3 一.搭建IIS服务器 二.身份验证和权限设置 三.IP地址和域名限制 四.安全通信 五. 单点登录  实验总结 1. 了解什么是XSS 2. 掌握盗

    2024年02月13日
    浏览(44)
  • 网络安全-Web端安全协议

    大家上网娱乐或办公总是离不开浏览器,也就是从web端访问各个网站,其安全的重要性与其使用的广泛性成正比。本文就web端常见的相关安全协议分享。 SSL(Secure Sockets Layer),安全套接层,它是在传输通信协议(TCP/IP)上实现的一种安全协议,它位于应用层协议之下且独立的

    2024年02月08日
    浏览(44)
  • 网络安全-安全Web网关(SWG)详解

    在当今快速发展的网络环境中,企业面临着越来越多的网络安全挑战。安全Web网关(SWG)作为一种高效的网络安全解决方案,为企业提供了一个安全、可控的网络使用环境。 安全Web网关是一种网络安全设备或服务,主要功能是监控和管理用户的Web访问,以防止恶意软件入侵和

    2024年02月01日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包