openssl3.2 - 官方demo学习 - signature - EVP_EC_Signature_demo.c

文章目录

    • openssl3.2 - 官方demo学习 - signature - EVP_EC_Signature_demo.c
    • 概述
    • 笔记
    • END

openssl3.2 - 官方demo学习 - signature - EVP_EC_Signature_demo.c

概述

EC的签名/验签实现, 摘要算法为 SHA3-512
签名验签时的update铭文可以进行多次.

openssl的API封装的真好, 只要是一类流程(e.g. 签名/验签), 采用不同算法时, 差别不大.

以前看资料, 那个老师说, 最好不要用名字来取算法指针, 容易写错. 而且调用的API比较麻烦.

已经单步调试了几十个官方demo, 官方全部采用名称字符串来取东西.
说明, 用名字取东西, 才可以让同一类操作的维护性最好.

看了一眼openSSL的底层用名字取东西的实现, 人家是做了一个Map, Map的成员是一个结构指针, 里面有名字和任务指针.
没仔细看, Map的Key应该是个hash值, 效率肯定刚刚的.

至于名称字符串容易写错, 自己准备一个用名字取东西的API的名字有效值的文档就可以搞定这个问题.

笔记

/*!
\file EVP_EC_Signature_demo.c
\note openssl3.2 - 官方demo学习 - signature - EVP_EC_Signature_demo.cEC的签名/验签实现, 摘要算法为 SHA3-512
签名验签时的update铭文可以进行多次.openssl的API封装的真好, 只要是一类流程(e.g. 签名/验签), 采用不同算法时, 差别不大.以前看资料, 那个老师说, 最好不要用名字来取算法指针, 容易写错. 而且调用的API比较麻烦.已经单步调试了几十个官方demo, 官方全部采用名称字符串来取东西.
说明, 用名字取东西, 才可以让同一类操作的维护性最好.看了一眼openSSL的底层用名字取东西的实现, 人家是做了一个Map, Map的成员是一个结构指针, 里面有名字和任务指针.
没仔细看, Map的Key应该是个hash值, 效率肯定刚刚的.至于名称字符串容易写错, 自己准备一个用名字取东西的API的名字有效值的文档就可以搞定这个问题.
*//*-* Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.** Licensed under the Apache License 2.0 (the "License").  You may not use* this file except in compliance with the License.  You can obtain a copy* in the file LICENSE in the source distribution or at* https://www.openssl.org/source/license.html*//** An example that uses the EVP_MD*, EVP_DigestSign* and EVP_DigestVerify** methods to calculate and verify a signature of two static buffers.*/#include <string.h>
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/decoder.h>
#include "EVP_EC_Signature_demo.h" /*!< 头文件中只有私钥/公钥的数组定义 数组数据是EC的DER格式的私钥/公钥 */ #include "my_openSSL_lib.h"/** This demonstration will calculate and verify a signature of data using* the soliloquy from Hamlet scene 1 act 3*/static const char *hamlet_1 ="To be, or not to be, that is the question,\n""Whether tis nobler in the minde to suffer\n""The slings and arrowes of outragious fortune,\n""Or to take Armes again in a sea of troubles,\n"
;
static const char *hamlet_2 ="And by opposing, end them, to die to sleep;\n""No more, and by a sleep, to say we end\n""The heart-ache, and the thousand natural shocks\n""That flesh is heir to? tis a consumation\n"
;/** For demo_sign, load EC private key priv_key from priv_key_der[].* For demo_verify, load EC public key pub_key from pub_key_der[].*/
static EVP_PKEY *get_key(OSSL_LIB_CTX *libctx, const char *propq, int public)
{OSSL_DECODER_CTX *dctx = NULL;EVP_PKEY  *pkey = NULL;int selection;const unsigned char *data;size_t data_len;if (public) {selection = EVP_PKEY_PUBLIC_KEY;data =  pub_key_der;data_len = sizeof(pub_key_der);} else {selection =  EVP_PKEY_KEYPAIR;data = priv_key_der;data_len = sizeof(priv_key_der);}dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, "EC",selection, libctx, propq);(void)OSSL_DECODER_from_data(dctx, &data, &data_len);OSSL_DECODER_CTX_free(dctx);if (pkey == NULL)fprintf(stderr, "Failed to load %s key.\n", public ? "public" : "private");return pkey;
}static int demo_sign(OSSL_LIB_CTX *libctx,  const char *sig_name,size_t *sig_out_len, unsigned char **sig_out_value)
{int ret = 0, public = 0;size_t sig_len;unsigned char *sig_value = NULL;const char *propq = NULL;EVP_MD_CTX *sign_context = NULL;EVP_PKEY *priv_key = NULL;/* Get private key */priv_key = get_key(libctx, propq, public);if (priv_key == NULL) {fprintf(stderr, "Get private key failed.\n");goto cleanup;}/** Make a message signature context to hold temporary state* during signature creation*/sign_context = EVP_MD_CTX_new();if (sign_context == NULL) {fprintf(stderr, "EVP_MD_CTX_new failed.\n");goto cleanup;}/** Initialize the sign context to use the fetched* sign provider.*/if (!EVP_DigestSignInit_ex(sign_context, NULL, sig_name,libctx, NULL, priv_key, NULL)) {fprintf(stderr, "EVP_DigestSignInit_ex failed.\n");goto cleanup;}/** EVP_DigestSignUpdate() can be called several times on the same context* to include additional data.*/if (!EVP_DigestSignUpdate(sign_context, hamlet_1, strlen(hamlet_1))) {fprintf(stderr, "EVP_DigestSignUpdate(hamlet_1) failed.\n");goto cleanup;}if (!EVP_DigestSignUpdate(sign_context, hamlet_2, strlen(hamlet_2))) {fprintf(stderr, "EVP_DigestSignUpdate(hamlet_2) failed.\n");goto cleanup;}/* Call EVP_DigestSignFinal to get signature length sig_len */if (!EVP_DigestSignFinal(sign_context, NULL, &sig_len)) {fprintf(stderr, "EVP_DigestSignFinal failed.\n");goto cleanup;}if (sig_len <= 0) {fprintf(stderr, "EVP_DigestSignFinal returned invalid signature length.\n");goto cleanup;}sig_value = OPENSSL_malloc(sig_len);if (sig_value == NULL) {fprintf(stderr, "No memory.\n");goto cleanup;}if (!EVP_DigestSignFinal(sign_context, sig_value, &sig_len)) {fprintf(stderr, "EVP_DigestSignFinal failed.\n");goto cleanup;}*sig_out_len = sig_len;*sig_out_value = sig_value;fprintf(stdout, "Generating signature:\n");BIO_dump_indent_fp(stdout, sig_value, (int)sig_len, 2);fprintf(stdout, "\n");ret = 1;cleanup:/* OpenSSL free functions will ignore NULL arguments */if (!ret)OPENSSL_free(sig_value);EVP_PKEY_free(priv_key);EVP_MD_CTX_free(sign_context);return ret;
}static int demo_verify(OSSL_LIB_CTX *libctx, const char *sig_name,size_t sig_len, unsigned char *sig_value)
{int ret = 0, public = 1;const char *propq = NULL;EVP_MD_CTX *verify_context = NULL;EVP_PKEY *pub_key = NULL;/** Make a verify signature context to hold temporary state* during signature verification*/verify_context = EVP_MD_CTX_new();if (verify_context == NULL) {fprintf(stderr, "EVP_MD_CTX_new failed.\n");goto cleanup;}/* Get public key */pub_key = get_key(libctx, propq, public);if (pub_key == NULL) {fprintf(stderr, "Get public key failed.\n");goto cleanup;}/* Verify */if (!EVP_DigestVerifyInit_ex(verify_context, NULL, sig_name,libctx, NULL, pub_key, NULL)) {fprintf(stderr, "EVP_DigestVerifyInit failed.\n");goto cleanup;}/** EVP_DigestVerifyUpdate() can be called several times on the same context* to include additional data.*/if (!EVP_DigestVerifyUpdate(verify_context, hamlet_1, strlen(hamlet_1))) {fprintf(stderr, "EVP_DigestVerifyUpdate(hamlet_1) failed.\n");goto cleanup;}if (!EVP_DigestVerifyUpdate(verify_context, hamlet_2, strlen(hamlet_2))) {fprintf(stderr, "EVP_DigestVerifyUpdate(hamlet_2) failed.\n");goto cleanup;}if (EVP_DigestVerifyFinal(verify_context, sig_value, sig_len) <= 0) {fprintf(stderr, "EVP_DigestVerifyFinal failed.\n");goto cleanup;}fprintf(stdout, "Signature verified.\n");ret = 1;cleanup:/* OpenSSL free functions will ignore NULL arguments */EVP_PKEY_free(pub_key);EVP_MD_CTX_free(verify_context);return ret;
}int main(void)
{OSSL_LIB_CTX *libctx = NULL;const char *sig_name = "SHA3-512";size_t sig_len = 0;unsigned char *sig_value = NULL;int ret = EXIT_FAILURE;libctx = OSSL_LIB_CTX_new();if (libctx == NULL) {fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");goto cleanup;}if (!demo_sign(libctx, sig_name, &sig_len, &sig_value)) {fprintf(stderr, "demo_sign failed.\n");goto cleanup;}if (!demo_verify(libctx, sig_name, sig_len, sig_value)) {fprintf(stderr, "demo_verify failed.\n");goto cleanup;}ret = EXIT_SUCCESS;cleanup:if (ret != EXIT_SUCCESS)ERR_print_errors_fp(stderr);/* OpenSSL free functions will ignore NULL arguments */OSSL_LIB_CTX_free(libctx);OPENSSL_free(sig_value);return ret;
}

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python PyQt5的学习

一、安装与配置 1、环境&#xff1a; python3.7 2、相关模块 pip install pyqt5 pyqt5-tools pyqt5designer 可以加个镜像 -i https://pypi.tuna.tsinghua.edu.cn/simple3、配置设计器 python的pyqt5提供了一个设计器&#xff0c;便于ui的设计 界面是这样的&#xff1a…

springboot实现微信小程序授权登录前后端代码完整版

一个简单的微信授权登录的demo&#xff0c;我这边没有建表&#xff0c;是存到redis里面了&#xff0c;仅供参考&#xff0c;后续可以扩展自己的业务逻辑&#xff0c;把登录信息存在表里面。 前端小程序代码&#xff1a; <view><view class"login-icon">…

ABAP - 读取长文本优化

做程序优化的时候发现在循环里面读取长文本&#xff0c;用&#xff08;READ_TEXT\类的方法&#xff09;读取太消耗性能了&#xff0c;于是用读取底表的方法去取。 DATA lt_stxl_raw TYPE TABLE OF ty_stxl_raw.DATA ls_stxl_raw TYPE ty_stxl_raw.DATA lt_tline TY…

MFC为资源对话框添加消息处理函数和初始化控件

现在我VC6新建了一个对话框工程&#xff1b;又在资源添加了一个新的对话框&#xff0c;并为新的对话框添加了名为CTestDlg的类&#xff1b; 在主对话框的cpp文件包含#include "TestDlg.h"&#xff1b; 在主对话框的cpp文件的OnInitDialog()成员函数中&#xff0c;添…

算法之回溯动态规划贪心

回溯使用场景&#xff1a;求出所有可能的解。 List result; void backtrack(路径,选择列表){if(满足结束条件){result.add(路径);return;}for(选择:选择列表){// 遍历集合中的元素做选择;backtrack(路径,选择列表);撤销选择;} }动态规划使用场景&#xff1a;寻求最优解。 #初…

单列的堆叠柱状图

目的 MSingleColumnStackBarChart类被设计用于创建只有单列的堆叠柱状图&#xff0c;用于血糖数据的统计。以下是封装这个类的目的的详细描述&#xff1a; 抽象复杂性&#xff1a; 通过创建MSingleColumnStackBarChart类&#xff0c;你将复杂的MPAndroidChart库的使用和配置封…

12166 - Equilibrium Mobile (UVA)

题目链接如下&#xff1a; Online Judge 一个很简洁的写法&#xff1a;UVa 12166 Equilibrium Mobile——思路题_equilibrium mobile uva - 12166-CSDN博客 才33行&#xff0c;真的NB坏了…… 我的比较繁琐的代码&#xff08;能AC&#xff09;&#xff0c;比较之下就能发现…

VUE---组件的样式冲突scoped

默认情况 &#xff1a;写在组件中的样式会 全局生效 &#xff0c;因此很容易造成多个组件之间的样式冲突问题。 1、 全局样式 &#xff1a; 默认组件中的样式会作用到全局 2、 局部样式 &#xff1a; 可以给组件加上 scoped 属性&#xff0c; 让样式只作用于当前组件 sc…

FastGPT + Xinference + OneAPI:一站式本地 LLM 私有化部署和应用开发

Excerpt 随着 GPTs 的发布,构建私有知识库变得无比简易,这为个人创建数字化身份、第二大脑,或是企业建立知识库,都提供了全新的途径。然而,基于众所周知的原因,GPTs 在中国的使用依然存在诸多困扰和障碍。因此,在当… 随着 GPTs 的发布,构建私有知识库变得无比简易,这…

React全局状态管理

redux是一个状态管理框架&#xff0c;它可以帮助我们清晰定义state和处理函数&#xff0c;提高可读性&#xff0c;并且redux中的状态是全局共享&#xff0c;规避组件间通过props传递状态等操作。 快速使用 在React应用的根节点&#xff0c;需要借助React的Context机制存放整个…

深入探讨 Go 语言中的 Map 类型

深入探讨 Go 语言中的 Map 类型 Go 语言中的 map 类型是一种非常强大且常用的数据结构&#xff0c;它提供了一种键值对的映射关系。本篇博客将深入讨论 Go 中的 map 类型&#xff0c;包括其基本用法、特性、以及一些最佳实践。 基本概念 1. 声明和初始化 在 Go 中&#xff…

mobi文件怎么转换成pdf?

mobi文件怎么转换成pdf&#xff1f;在数字化时代&#xff0c;电子书籍成为了越来越受欢迎的阅读方式。我们可以通过多种格式的电子书来获取知识和娱乐&#xff0c;其中一种常见的格式就是Mobi文件。Mobi文件是亚马逊公司开发的一种电子书格式&#xff0c;它主要用于Kindle设备和…

SL4010升压恒压电源芯片DC3.7V升压5V、12V、24V/5A

SL4010是一款升压恒压电源芯片&#xff0c;可以将DC3.7V的输入电压升压至5V、12V或24V的输出电压&#xff0c;并可提供高达5A的输出电流。这款芯片采用了先进的升压技术&#xff0c;能够实现高效、稳定的电压转换&#xff0c;同时还具有低噪声、低功耗和低成本等优点。在各种需…

【论文阅读】Consistency Models

文章目录 IntroductionDiffusion ModelsConsistency ModelsDefinitionParameterizationSampling Training Consistency Models via DistillationTraining Consistency Models in IsolationExperiment Introduction 相比于单步生成的模型&#xff08;例如 GANs, VAEs, normalizi…

推荐几个Github高星GoLang管理系统

在Web开发领域&#xff0c;Go语言&#xff08;Golang&#xff09;以其高效、简洁、高并发等特性逐渐成为许多开发者的首选语言。有许多优秀的Go语言Web后台管理系统&#xff0c;这些项目星星众多&#xff0c;提供了丰富的功能和良好的代码质量。本文将介绍一些GitHub高星的GoLa…

学会这个昼夜系统,你也能做出一款饥荒生存类游戏DEMO!

学会这个昼夜系统&#xff0c;你也能做出一款饥荒生存类游戏DEMO&#xff01; 《饥荒》作为生存类游戏的老大哥&#xff0c;深受大家喜爱&#xff0c;这款游戏于2012年年底正式公测上线&#xff0c;距今已有10年的时间&#xff0c;从最初的单机版慢慢推出了联机版&#xff0c;…

Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务

技术背景 我们在对接Unity下推送模块的时候&#xff0c;遇到这样的技术诉求&#xff0c;开发者希望在Android的Unity场景下&#xff0c;获取到前后摄像头的数据&#xff0c;并投递到RTMP服务器&#xff0c;实现低延迟的数据采集处理。 在此之前&#xff0c;我们已经有了非常成…

大模型学习之书生·浦语大模型5——基于LMDeploy大模型量化部署实践

目录 大模型部署背景 LMDeploy部署 量化 TurboMind API server 动手实践环节

LCR 173. 点名(二分)

一、题目描述 LCR 173. 点名 某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席&#xff0c;请返回他的学号。 示例 1: 输入: records [0,1,2,3,5] 输出: 4示例 2: 输入: records [0, 1, 2, 3, 4, 5, 6, 8] 输出: 7 二、题目解析…

flink1.14.5使用CDH6.3.2的yarn提交作业

使用CDH6.3.2安装了hadoop集群&#xff0c;但是CDH不支持flink的安装&#xff0c;网上有CDH集成flink的文章&#xff0c;大都比较麻烦&#xff1b;但其实我们只需要把flink的作业提交到yarn集群即可&#xff0c;接下来以CDH yarn为基础&#xff0c;flink on yarn模式的配置步骤…