openssl engine 实现SM4 引擎

2023-11-04


一 openssl engine基本介绍

Engine机制目的是为了使OpenSSL能够透明地使用第三方提供的软件加密库或者硬件加密设备进行加密。OpenSSL的Engine机制成功地达到了这个目的,这使得OpenSSL已经不仅仅使一个加密库,而是提供了一个通用地加密接口,能够与绝大部分加密库或者加密设备协调工作。当然,要使特定加密库或加密设备更OpenSSL协调工作,需要写少量的接口代码,但是这样的工作量并不大。

二 SM4引擎实现

1 Openssl定义好的主接口

IMPLEMENT_DYNAMIC_BIND_FN(bind)
IMPLEMENT_DYNAMIC_CHECK_FN()

2 定义bind函数

bind函数的定义如下所示:

static int bind(ENGINE *e, const char *id)
{
  int ret = 0;

  if (!ENGINE_set_id(e, engine_id)) {
    fprintf(stderr, "ENGINE_set_id failed\n");
    goto end;
  }
  if (!ENGINE_set_name(e, engine_name)) {
    printf("ENGINE_set_name failed\n");
    goto end;
  }
  if (!ENGINE_set_ciphers(e, ciphers)) {
    printf("ENGINE_set_name failed\n");
    goto end;
  }

  ret = 1;
 end:
  return ret;
}

其中主要是使用openssl的引擎API注册和设置sm4引擎,

3 实现ciphers函数

ciphers函数是配置算法结构初始化函数,其定义如下所示:

static int ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                   const int **nids, int nid)
{
  int ok = 1;
  #if 1
  if (!cipher) {
    /* We are returning a list of supported nids */
    *nids = sm4_nids;
    return (sizeof(sm4_nids) - 1) / sizeof(sm4_nids[0]);
  }
  #endif

  switch (nid) {
  case NID_aes_128_ecb:
    *cipher = &cipher_sm4;
    break;
  default:
    ok = 0;
    *cipher = NULL;
    break;
  }
  return ok;
}

4 定义算法结构evp_cipher_st

定义如下

struct evp_cipher_st cipher_sm4 =
	{
	NID_aes_128_ecb,//int nid;
	16,//int block_size;
	16,//int key_len;		/* Default value for variable length ciphers */
	16,//int iv_len;
	0,//unsigned long flags;	/* Various flags */
	sm4_init,//int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
		  //  const unsigned char *iv, int enc);	/* init key */
	sm4_func,//int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
		//	 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
	NULL,//int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
	sizeof(sm4_ctx_t),//int ctx_size;		/* how big ctx->cipher_data needs to be */
	NULL,//int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
	NULL,//int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
	NULL,//int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
	NULL,//void *app_data;		/* Application data */
	} /* EVP_CIPHER */;

在算法结构中,定义了如下信息
(1)指明了算法ID,由于我使用的openssl是1.0版本,还不支持sm4算法,目前只能使用aes的id来代替。
(2) 定义了key和iv的长度,都为16字节
(3)定义了sm4_init 函数,用于初始化sm4算法,包括key 和id。
(4) 定义了sm4_func函数,用于sm4算法的加解密的实现。
(5) 定义了sm4_ctx_t 结构的大小,这个结构体中包括了sm4密钥和加解密标志。
(6)其他没有用到的元素都置NULL

5 实现sm4_init 函数体

int sm4_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
		    const unsigned char *iv, int enc)
{
    sm4_ctx_t *sm4_contex;
    sm4_contex=(sm4_ctx_t *)(ctx->cipher_data);
    memcpy(sm4_contex->key,key,16);
    sm4_contex->enc_dec=enc;
    dump_hex("sm4_init get key",sm4_contex->key,16);
    printf("get enc flag: %d\n",sm4_contex->enc_dec);
}

6 实现sm4_func 函数体

int sm4_func(EVP_CIPHER_CTX *ctx, unsigned char *out,
			 const unsigned char *in, size_t inl)
{
    sm4_ctx_t *sm4_contex;
    sm4_contex=(sm4_ctx_t *)(ctx->cipher_data);
    if(sm4_contex->enc_dec)
    {
        dump_hex("plain data:",in,16);
        SM4_Encrypt(sm4_contex->key,in,out);
        dump_hex("enc data:",out,16);
    }
    else
    {
        dump_hex("cipher data:",in,16);
        SM4_Decrypt(sm4_contex->key,in,out);
        dump_hex("dec data:",out,16);
    }
}

7编译和测试

make  //编译出so文件,这个就是sm4的加密引擎库
make test 调用openssl命令进行测试该引擎

结果如下:

$ make test
openssl engine -t -c `pwd`/./bin/sm4-engine.so
(/home/yaomingyue/work/openssl/test/engine/sm4/v2/./bin/sm4-engine.so) A simple SM4 engine for demonstration purposes
Loaded: (SM4) A simple SM4 engine for demonstration purposes
 [AES-128-ECB]
     [ available ]
echo whatever | openssl enc -aes-128-ecb -e -out out.bin -K 0123456789ABCDEFFEDCBA9876543210 -iv 0123456789ABCDEFFEDCBA9876543210 -engine `pwd`/bin/sm4-engine.so
engine "SM4" set.
sm4_init get key:
1 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 
get enc flag: 1
plain data::
77 68 61 74 65 76 65 72 a 7 7 7 7 7 7 7 
enc data::
b6 63 68 23 aa ae f2 a6 e3 4 ac 33 ea 4b b2 2d 
openssl enc -aes-128-ecb -d -in out.bin -K 0123456789ABCDEFFEDCBA9876543210 -engine `pwd`/bin/sm4-engine.so
engine "SM4" set.
sm4_init get key:
1 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 
get enc flag: 0
cipher data::
b6 63 68 23 aa ae f2 a6 e3 4 ac 33 ea 4b b2 2d 
dec data::
77 68 61 74 65 76 65 72 a 7 7 7 7 7 7 7 
whatever

本文章相关源码

https://download.csdn.net/download/qq_39952971/30319470

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openssl engine 实现SM4 引擎 的相关文章

随机推荐

  • 论文解读:Factuality Enhanced Language Models for Open-Ended Text Generation

    论文解读 Factuality Enhanced Language Models for Open Ended Text Generation Github https github com nayeon7lee FactualityPro
  • 比中年危机更可怕的,是“下半生危机”

    比中年危机更可怕的 是 下半生危机 原创 2018 03 11 叶开甫 正和岛 岛 君 说 退休这个概念 正变得越来越不重要 中年危机并不可怕 可怕的是 下半生危机 工作失去乐趣 生活满腹牢骚 正如彼得 德鲁克在 21世纪的管理挑战 里所揭
  • 【华为OD统一考试B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一
  • QMessageBox信息模态对话框详细使用教程,对象创建栈和指针类型,对话框的风格样式设置,不要浪费实时间自己封装了,图文并茂,看图说话。

    QMessageBox 界面设计图 展示效果 1 PC端使用QMessageBox information 常规信息 warning 警告消息 critical 错误信息 about 关于信息 无按钮 question 问题信息 嵌入式平台
  • python读取json和使用request模块

    To experiment with this code freely you will have to run this code locally Take a look at the main function for an examp
  • IDEA设置System.out.println()和main方法快捷键

    IDEA是Java开发中的神器 很多同学都用了IDEA来开发自己的Java应用 但苦于不知道怎么设置System out println 和main方法的快捷键 今天 咱们就一起来解决这个问题 首先 打开IDEA的File gt setti
  • 参考文献英文刊名的缩写规则

    本文参考国际标准ISO4 1984 文献工作 期刊刊名缩写的国际规则 及国家标准GB7714 87 文后参考文献著录规则 附录C 1 单个词组成的刊名不得缩写部分刊名由一个实词组成 如Adsorption Aerobiologia Radi
  • 利用 squid 反向代理提高网站性能

    本文在介绍 squid 反向代理的工作原理的基础上 指出反向代理技术在提高网站访问速度 增强网站可用性 安全性方面有很好的用途 作者在具体的实验环境下 利用 DNS 轮询和 Squid 反向代理技术 实现了网站的负载均衡 从而提高了网站的可
  • this.$emit()的用法

    this emit 是 Vue js 中的一个方法 它可以用于子组件向父组件传递事件 使用方法如下 this emit eventName args 其中 eventName 是事件名称 args 是可选参数 表示传递给父组件的数据 举个例
  • shell脚本抽取文本文件中指定字符串的方法:sed+grep方法、awk+grep方法(必要时可以联合sed以及grep)、grep+cut方法

    在linux中经常要对一些动态的文本文件抽取指定的字符串 比如执行ps命令后想要获取指定的运行进程 如ps自己 的PID号 同一个进程每次启动的时候pid号是随机分配的 该怎么办呢 当然 可以用一些截取字符串的方法 这里介绍一下用2种方法来
  • js根据数组中对象的某个属性值进行去重

    var arr from 张三 to 河南 from 王二 to 阿里 from 王二 to 杭州 from 王二 to 山东 有如上数组 想根据数组中的对象的from属性进行去重 如果from一样的话 重复只保留一条 根据ES6属性编写函
  • Linux文件系统论述

    目录 前言 一 磁盘 1 1定义 1 2结构 1 3磁盘的寻找方式 1 4磁盘的逻辑 线性结构 1 5磁盘访问的基本单位 1 6磁盘的管理 二 Linux文件系统 2 1系统结构 2 2属性解析 2 3inode相关块的解析 2 4数据块的
  • TensorFlow

    用tensorflow实现线性回归 主要考察的是一个tf的一个实现思路 贝壳 import tensorflow as tf import numpy as np import matplotlib pyplot as plt 使用nump
  • 【网络协议详解】——BGP协议(学习笔记)

    目录 1 概述 2 BGP 发言人 3 工作原理 4 报文格式 4 1 报文首部 4 2 打开报文 4 3 更新报文 4 4 保活报文 4 5 通知报文 5 BGP 的路径属性 5 1 origin 属性 5 2 AS PATH 属性 5
  • 第四讲. 经典算法之哈希映射

    第四讲 经典算法之哈希映射 1 简介 2 从一个简单例题开始 3 哈希中的碰撞冲突 3 1 线性探测法 3 2 链地址法 3 3 再哈希法 3 4 4 哈希函数的设计 4 1 更大的哈希表 4 2 更好的哈希运算 5 最后说几句 1 简介
  • 从零开始搭建基于vue的electron项目

    从零开始搭建基于vue的electron项目 1 需求背景 最近正在为基于electron的新项目做准备 本文章将为大家演示从零开始搭建基于vue的electron项目步骤 2 解决方案 1 将Vue引入Electron项目常用的两种方案分
  • 03云计算与大数据学习之云存储

    文章目录 1 应知应会 2 认识云存储 云存储 云存储技术的两种架构 云存储的种类 云存储的应用领域 3 参考文献 1 应知应会 云存储是一个以数据存储和管理为核心的云计算系统 云存储由存储节点和控制节点两个部分组成 云存储系统的结构模型由
  • notepad++快捷键

    notepad 快捷键 https wenku baidu com view 9dec474e021ca300a6c30c22590102020640f254 html wkts 1676528962334 bdQuery notepad
  • QT QTextEdit QTextBrowser追加文本不换行

    QTextEdit QTextBrowser两个控件追加文本的接口使用方法都是一样的 以QTextBrowser为例 1 追加文本自动换行 textBrowser gt append hello textBrowser gt append
  • openssl engine 实现SM4 引擎

    openssl engine 实现SM4 引擎 一 openssl engine基本介绍 二 SM4引擎实现 1 Openssl定义好的主接口 2 定义bind函数 3 实现ciphers函数 4 定义算法结构evp cipher st 5