openssl3.2 - exp - export RSA pubKey from RSA privKey on memory

文章目录

    • openssl3.2 - exp - export RSA pubKey from RSA privKey on memory
    • 概述
    • 笔记
    • END

openssl3.2 - exp - export RSA pubKey from RSA privKey on memory

概述

官方给的例子(openssl3.2 - 官方demo学习 - encode - rsa_encode.c)是基于文件操作的.

我的工程只需要openssl 操作内存数据, 改了一个操作buffer的版本.
从内存中的RSA私钥数据, 导出RSA公钥来用.

笔记

/*!
* \file main.cpp
* \note openssl3.2 - exp - export RSA pubKey from RSA privKey on memory
*/#include "my_openSSL_lib.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>
#include <openssl/decoder.h>
#include <openssl/encoder.h>
#include <openssl/evp.h>#include <stdlib.h>
#include <stdio.h>
#include <assert.h>#include "CMemHookRec.h"// 为了内存操作, 已经将私钥数据文件转成了数组, 嵌入到工程中
//! \ref https://lostspeed.blog.csdn.net/article/details/136486115
//! 数组为 const char ucAry_priv_key_for_test[1892];
#include "priv_key_for_test.h"
#include <cassert>void my_openssl_app();// 都是在操作内存, 从内存中的私钥数据, 转出到内存中的公钥数据
bool exportRsaPrivKeyToRsaPubKey(const char* pBufPrivKey, int lenPrivKey, const char* pBufPrivKeyPwd, char*& pBufPubKey, int& lenPubKey);EVP_PKEY* load_key(OSSL_LIB_CTX* libctx, const char* pBufPrivKey, int lenPrivKey, const char* passphrase);
bool export_Key(EVP_PKEY* pkey, const char* passphrase, char*& pBufPubKey, int& lenPubKey);int main(int argc, char** argv)
{setvbuf(stdout, NULL, _IONBF, 0); // 清掉stdout缓存, 防止调用printf时阻塞mem_hook();my_openssl_app();mem_unhook();/*! run resultb_rc = truethe rsa public key is below:0000 - 2d 2d 2d 2d 2d 42 45 47-49 4e 20 52 53 41 20 50   -----BEGIN RSA P0010 - 55 42 4c 49 43 20 4b 45-59 2d 2d 2d 2d 2d 0a 4d   UBLIC KEY-----.M0020 - 49 49 42 43 67 4b 43 41-51 45 41 6f 6a 62 54 2f   IIBCgKCAQEAojbT/0030 - 64 71 79 63 6b 2f 34 58-4a 79 54 45 45 49 34 63   dqyck/4XJyTEEI4c0040 - 51 76 77 49 33 6b 66 76-38 46 78 30 46 50 75 6b   QvwI3kfv8Fx0FPuk0050 - 53 41 6d 77 71 52 66 44-6b 55 46 57 57 4b 4c 0a   SAmwqRfDkUFWWKL.0060 - 7a 67 4a 6b 71 38 66 58-76 65 51 66 31 74 55 32   zgJkq8fXveQf1tU20070 - 32 71 50 70 51 69 6b 30-79 64 6a 75 59 55 35 75   2qPpQik0ydjuYU5u0080 - 47 41 45 34 68 36 64 45-36 66 45 75 79 75 7a 6e   GAE4h6dE6fEuyuzn0090 - 4a 43 32 4b 4b 51 47 55-76 74 71 52 6c 77 76 49   JC2KKQGUvtqRlwvI00a0 - 0a 2b 66 78 77 53 54 4d-45 2f 54 68 48 57 59 71   .+fxwSTME/ThHWYq00b0 - 43 41 76 58 5a 2f 49 52-4d 31 32 37 66 67 37 4a   CAvXZ/IRM127fg7J00c0 - 37 61 59 37 74 31 65 68-79 79 33 57 59 50 72 71   7aY7t1ehyy3WYPrq00d0 - 44 37 45 4c 78 75 37 6c-5a 65 36 4b 54 6f 50 59   D7ELxu7lZe6KToPY00e0 - 2b 0a 70 52 58 54 35 62-61 59 37 52 44 66 54 4c   +.pRXT5baY7RDfTL00f0 - 78 7a 76 31 54 68 63 4c-30 46 72 4b 32 70 62 6c   xzv1ThcL0FrK2pbl0100 - 31 59 48 32 30 31 58 57-67 6c 2b 46 51 62 31 6a   1YH201XWgl+FQb1j0110 - 70 41 51 75 4d 53 58 76-79 52 4a 56 79 69 6d 76   pAQuMSXvyRJVyimv0120 - 36 2b 0a 48 6e 67 6a 37-35 63 57 74 54 42 30 49   6+.Hngj75cWtTB0I0130 - 43 33 68 52 57 55 69 74-77 56 6c 43 4b 6f 76 61   C3hRWUitwVlCKova0140 - 57 54 63 43 49 4f 33 48-55 56 55 70 58 4a 78 4f   WTcCIO3HUVUpXJxO0150 - 73 51 71 63 34 58 46 2f-70 67 6e 4c 72 79 75 41   sQqc4XF/pgnLryuA0160 - 74 34 37 0a 71 56 6a 63-45 61 2f 42 58 68 38 75   t47.qVjcEa/BXh8u0170 - 79 6b 49 2b 30 34 6e 4e-58 79 34 66 6d 76 4a 48   ykI+04nNXy4fmvJH0180 - 4a 55 54 45 30 51 49 44-41 51 41 42 0a 2d 2d 2d   JUTE0QIDAQAB.---0190 - 2d 2d 45 4e 44 20 52 53-41 20 50 55 42 4c 49 43   --END RSA PUBLIC01a0 - 20 4b 45 59 2d 2d 2d 2d-2d 0a                      KEY-----.free map, g_mem_hook_map.size() = 0*/return 0;
}void my_openssl_app()
{bool b_rc = false;char* pszPubKey = NULL;int lenPubKey = 0;BIO* bio_out = BIO_new_fp(stdout, 0);assert(NULL != bio_out);do {// PWD_PRIV_KEY 是一个宏 char*, 定义在 priv_key_for_test.h 中, 是私钥数据的口令// 一般私钥数据做好时, 都是有口令的b_rc = exportRsaPrivKeyToRsaPubKey(ucAry_priv_key_for_test, sizeof(ucAry_priv_key_for_test), PWD_PRIV_KEY, pszPubKey, lenPubKey);BIO_printf(bio_out, "b_rc = %s\n", (b_rc ? "true" : "false"));if (!b_rc){assert(false);break;}// now can use pszPubKeyBIO_printf(bio_out, "the rsa public key is below:\n");BIO_dump_fp(stdout, pszPubKey, lenPubKey);} while (false);if (NULL != pszPubKey){OPENSSL_free(pszPubKey);pszPubKey = NULL;}if (NULL != bio_out){BIO_free(bio_out);bio_out = NULL;}
}bool exportRsaPrivKeyToRsaPubKey(const char* pBufPrivKey, int lenPrivKey, const char* pBufPrivKeyPwd, char*& pBufPubKey, int& lenPubKey)
{bool b_rc = false;EVP_PKEY* pubKey = NULL;do {// 如果ras私钥是没有口令保护的, 可以不给口令if ((NULL == pBufPrivKey) || (lenPrivKey <= 0)){break;}pubKey = load_key(NULL, pBufPrivKey, lenPrivKey, pBufPrivKeyPwd);if (NULL == pubKey){break;}if (!export_Key(pubKey, NULL, pBufPubKey, lenPubKey)){break;}b_rc = true;} while (false);if (NULL != pubKey){EVP_PKEY_free(pubKey);pubKey = NULL;}return b_rc;
}EVP_PKEY* load_key(OSSL_LIB_CTX* libctx, const char* pBufPrivKey, int lenPrivKey, const char* passphrase)
{int ret = 0;EVP_PKEY* pkey = NULL;OSSL_DECODER_CTX* dctx = NULL;int selection = 0;int i_tmp = 0;BIO* bio_privKey = BIO_new(BIO_s_mem());if (NULL == bio_privKey){goto cleanup;}i_tmp = BIO_write(bio_privKey, pBufPrivKey, lenPrivKey);if (i_tmp != lenPrivKey){goto cleanup;}/** Create PEM decoder context expecting an RSA key.** For raw (non-PEM-encoded) keys, change "PEM" to "DER".** The selection argument here specifies whether we are willing to accept a* public key, private key, or either. If it is set to zero, either will be* accepted. If set to EVP_PKEY_KEYPAIR, a private key will be required, and* if set to EVP_PKEY_PUBLIC_KEY, a public key will be required.*/dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, "RSA",selection,libctx, NULL);if (dctx == NULL) {// fprintf(stderr, "OSSL_DECODER_CTX_new_for_pkey() failed\n");goto cleanup;}/** Set passphrase if provided; needed to decrypt encrypted PEM files.* If the input is not encrypted, any passphrase provided is ignored.** Alternative methods for specifying passphrases exist, such as a callback* (see OSSL_DECODER_CTX_set_passphrase_cb(3)), which may be more useful for* interactive applications which do not know if a passphrase should be* prompted for in advance, or for GUI applications.*/if (passphrase != NULL) {if (OSSL_DECODER_CTX_set_passphrase(dctx,(const unsigned char*)passphrase,strlen(passphrase)) == 0) {// fprintf(stderr, "OSSL_DECODER_CTX_set_passphrase() failed\n");goto cleanup;}}/* Do the decode, reading from file. */if (OSSL_DECODER_from_bio(dctx, bio_privKey) == 0) { // 如果f是stdin, 就需要自己输入私钥内容, 所以函数入参的f必须是一个实际文件的FILE*// fprintf(stderr, "OSSL_DECODER_from_fp() failed\n");goto cleanup;}ret = 1;
cleanup:OSSL_DECODER_CTX_free(dctx);/** pkey is created by OSSL_DECODER_CTX_new_for_pkey, but we* might fail subsequently, so ensure it's properly freed* in this case.*/if (ret == 0) {EVP_PKEY_free(pkey);pkey = NULL;}if (NULL != bio_privKey){BIO_free(bio_privKey);bio_privKey = NULL;}return pkey;
}bool export_Key(EVP_PKEY* pkey, const char* passphrase, char*& pBufPubKey, int& lenPubKey)
{int ret = 0;int selection;OSSL_ENCODER_CTX* ectx = NULL;unsigned char* pdata = NULL;size_t sz_len_data = 0;/** Create a PEM encoder context.** For raw (non-PEM-encoded) output, change "PEM" to "DER".** The selection argument controls whether the private key is exported* (EVP_PKEY_KEYPAIR), or only the public key (EVP_PKEY_PUBLIC_KEY). The* former will fail if we only have a public key.** Note that unlike the decode API, you cannot specify zero here.** Purely for the sake of demonstration, here we choose to export the whole* key if a passphrase is provided and the public key otherwise.*/// 如果给出口令, 就导出公私钥对;// 如果不给口令, 就只导出公钥// 实际应用中, 我们就只有导出公钥的需求selection = (passphrase != NULL)? EVP_PKEY_KEYPAIR: EVP_PKEY_PUBLIC_KEY;ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "PEM", NULL, NULL);if (ectx == NULL) {// fprintf(stderr, "OSSL_ENCODER_CTX_new_for_pkey() failed\n");goto cleanup;}/** Set passphrase if provided; the encoded output will then be encrypted* using the passphrase.** Alternative methods for specifying passphrases exist, such as a callback* (see OSSL_ENCODER_CTX_set_passphrase_cb(3), just as for OSSL_DECODER_CTX;* however you are less likely to need them as you presumably know whether* encryption is desired in advance.** Note that specifying a passphrase alone is not enough to cause the* key to be encrypted. You must set both a cipher and a passphrase.*/if (passphrase != NULL) {/* Set cipher. AES-128-CBC is a reasonable default. */if (OSSL_ENCODER_CTX_set_cipher(ectx, "AES-128-CBC", NULL) == 0) {// fprintf(stderr, "OSSL_ENCODER_CTX_set_cipher() failed\n");goto cleanup;}/* Set passphrase. */if (OSSL_ENCODER_CTX_set_passphrase(ectx,(const unsigned char*)passphrase,strlen(passphrase)) == 0) {// fprintf(stderr, "OSSL_ENCODER_CTX_set_passphrase() failed\n");goto cleanup;}}/* Do the encode, writing to the given file. */if (OSSL_ENCODER_to_data(ectx, &pdata, &sz_len_data) == 0) {// fprintf(stderr, "OSSL_ENCODER_to_fp() failed\n");goto cleanup;}pBufPubKey = (char*)pdata;lenPubKey = (int)sz_len_data;ret = 1;
cleanup:OSSL_ENCODER_CTX_free(ectx);return ret;
}

END

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

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

相关文章

【Ubuntu】原生Ubuntu-dock 栏 安装与卸载

1.查看是否安装 Ubuntu-dock&#xff08;新版本的Ubuntu自带Ubuntu-dock version> 18.04&#xff09; gnome-extensions list 2.安装Ubuntu-dock sudo apt install gnome-shell-extension-ubuntu-dock 3.重启&#xff0c;一定要重启&#xff01;&#xff01;&#xff01;…

LeetCode2.07链表相交

2.07链表相交 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结…

Linux中排查磁盘存储不足问题Centos7.9

操作系统Centos7.9 df -h # 命令查看磁盘空间 du -ah --max-depth1 / # 查看根目录下各个文件占用情况max-depth表示目录的深度。 查看某个目录du -bsh命令&#xff0c;看一下常用的usr目录大小 du -bsh /usr 进入目录用find命令找到大于100M文件find . -size 100M&#xff…

vue实现图片框选标注

前言 前端有一个需求&#xff0c;对上传的图片进行检测识别&#xff0c;通过返回的接口坐标数据&#xff0c;对图片的某些区域进行框选并标注。如图&#xff1a; 开始 1、上传功能使用elementui的upload插件&#xff1b; 2、在图片上进行标注功能是元素定位在图片上层&#x…

Java - 探究Java优雅退出的两种机制

文章目录 概述Java优雅停机_ ShutdownHook 机制步骤Code Java优雅停机_ 信号量机制SignalHandler 工作原理使用步骤Linux支持的信号量根据操作系统选择信号量Code 注意事项 概述 在Linux上通过kill -9 pid方式强制终止进程的副作用&#xff0c;这种方式虽然简单高效&#xff0…

SpringBoot项目中同时支持https和http协议

实用干货&#xff01;看壹哥如何在SpringBoot项目中同时支持https和http协议_springboot http htpps共存-CSDN博客

网络学习DAY3--TCP并发

思路一&#xff1a;多线程并发 缺点&#xff1a;资源浪费过大&#xff0c;且能实现的并发量有限。 思路二&#xff1a;IO通信 1.阻塞IO 没有任务时&#xff0c;挂起任务&#xff0c;节省资源&#xff0c;提高效率 2.非阻塞IO 未收到数据时一直执行&#xff0c;效率很低 …

小红书素人投放计划怎么做?

小红书素人投放是很多品牌在小红书推广打响的第一枪&#xff0c;素人铺量在小红书投放&#xff0c;可以奠定品牌在小红书的声量&#xff0c;小红书素人投放计划怎么做&#xff1f;前期规划好一切&#xff0c;才能在后期让我们的推广爆发出更好的效果。接下来伯乐网络传媒就来给…

【压缩包技巧】如何把rar文件压缩为zip格式?

想要将rar文件压缩为zip格式&#xff0c;其实就是压缩包格式进行转换&#xff0c;今天和大家分享三个rar压缩包改成zip格式的方法&#xff0c;希望能够帮助到大家&#xff01; 方法一&#xff1a; 直接修改rar压缩包的后缀名变为zip&#xff0c;就可以修改压缩包文件格式了 …

MySQL 排错 - blocked because of many connection errors

文章目录 说明1. host_cache2. 问题复现2.1 未调用 close()2.2 MySQL 协议握手错误 3. 解决方法 说明 前几天收到了研发同学反馈&#xff0c;测试环境的数据库出现了无法连接的情况&#xff0c;并附上了报错&#xff0c;本篇文章分析该异常的原因。 ERROR 1129 (HY000): Host …

揭秘Google Gemini:AI界的多模态革命者与ChatGPT-4的较量

在人工智能的快速发展浪潮中&#xff0c;Google DeepMind的最新力作——Gemini&#xff0c;以其多模态的超凡能力&#xff0c;正引领着AI技术的新一轮革命。本文将深入探讨Gemini的核心特性、不同版本的特点&#xff0c;以及它与ChatGPT-4的对比优势和差异。 一、Gemini简介 A…

Java SE入门及基础(35)

接口 1. 概念 在软件工程中&#xff0c;软件与软件的交互很重要&#xff0c;这就需要一个约定。每个程序员都应该能够编写实现这样的约定。接口就是对约定的描述。 In the Java programming language, an interface is a reference type, similar to a class, that can con…

float32 float16 bfloat16 推理训练GPU速度和内存调研

概念&#xff1a; 参考&#xff1a;Accelerating Large Language Models with Mixed-Precision Techniques - Lightning AI 3种数量类型表示的数据范围不一样&#xff0c;以float32为例其中有1个符号位&#xff0c;8位表示指数&#xff0c;23位表示尾数 标准训练推理是用的fl…

团体程序设计天梯赛 L2-013 红色警报(连通分量)

L2-013 红色警报 分数 25 战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序&#xff0c;当失去一个城市导致国家被分裂为多个无法连通的区域时&#xff0c;就发出红色警报。注意&#xff1a;若该国本来就不完全连通&#xff0c;是分裂的k个区域&#xff0c…

eclipse maven 项目导入报错

错误&#xff1a;Internal compiler error: java.lang.NullPointerException at org.eclipse.jdt.internal.compiler.apt.dispatch.AnnotationDiscoveryVisitor 环境&#xff1a;eclipse Kepler Service Release 2 ,JDK1.7 解决办法&#xff1a;编码不对&#xff0c;修改

前端自带的base64转化方法

前端html的base64使用方法window.btoa()和window.atob()_html用window.btoa();-CSDN博客

ubuntu20.04缺少libssl.so.1.0.0的解决方法

Index of /ubuntu/pool/main/o/openssl 使用一下下载命令&#xff0c;注意如果提示安装包不存在&#xff0c;可以从上述链接中找到合适的安装包&#xff0c;下载安装 wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu4.20_amd64.debsu…

指令调用模板

也就是这边指令通过id和map会定位到一个结构体&#xff0c;然后这个结构再赋值两个成员&#xff0c;一个是函数一个是指令类型&#xff0c;然后这个函数是模板的实例化 使用的时候就传进去&#xff0c;这只是参数&#xff0c;最开始初始化的时候模板就已经实例化了。然后关于模…

为什么美国硅谷作为服务器托管的首选地?

在数字化时代&#xff0c;服务器托管已成为企业运营不可或缺的一部分。而美国硅谷作为全球科技创新的摇篮&#xff0c;其服务器托管服务备受全球企业青睐。那么&#xff0c;为什么众多企业选择美国硅谷作为服务器托管的首选地呢? 硅谷拥有得天独厚的地理位置和网络基础设施。硅…

[HackMyVM]Quick 2

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Un…