openssl3.2 - exp - generate ecc priv key

文章目录

    • [openssl3.2 - exp - generate ecc priv key](#openssl3.2 - exp - generate ecc priv key)
    • 概述
    • 笔记
    • 备注
    • END

openssl3.2 - exp - generate ecc priv key

概述

前面实验已经将ECC加解密的流程用openssl命令模拟出来了.

现在开始将ECC加解密流程中的知识点从openssl.exe源码中迁移到自己工程.

先迁移了一个命令如下

openssl ecparam -name sect571r1 -genkey -noout -out priv_key_s.pem

封装了一个函数, 产生ecc密钥到buffer, 好使.

笔记

c 复制代码
/*!
* \file exp020_ecc_gen_priv_key.cpp
* \note openssl3.2 - exp - generate ecc priv key
	产生ECC私钥
	单步调试, 移植openssl命令行的实现
	openssl ecparam -name sect571r1 -genkey -noout -out priv_key_s.pem
*/

#include "my_openSSL_lib.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/encoder.h>

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include "CMemHookRec.h"

void my_openssl_app();
bool my_ecc_gen_priv_key(const char* keytype, const char* curve_name, const char* out_format, unsigned char*& pdata, size_t& data_len);

int main(int argc, char** argv)
{
	setvbuf(stdout, NULL, _IONBF, 0); // 清掉stdout缓存, 防止调用printf时阻塞
	mem_hook();

	my_openssl_app();

	mem_unhook();

	/*! run result
	ec priv key:
	0000 - 2d 2d 2d 2d 2d 42 45 47-49 4e 20 45 43 20 50 52   -----BEGIN EC PR
	0010 - 49 56 41 54 45 20 4b 45-59 2d 2d 2d 2d 2d 0a 4d   IVATE KEY-----.M
	0020 - 49 48 75 41 67 45 42 42-45 67 43 53 4d 2f 56 6a   IHuAgEBBEgCSM/Vj
	// ...
	0160 - 2b 31 64 0a 58 41 3d 3d-0a 2d 2d 2d 2d 2d 45 4e   +1d.XA==.-----EN
	0170 - 44 20 45 43 20 50 52 49-56 41 54 45 20 4b 45 59   D EC PRIVATE KEY
	0180 - 2d 2d 2d 2d 2d 0a                                 -----.
	free map, g_mem_hook_map.size() = 0
	*/

	return 0;
}

void my_openssl_app()
{
	bool b_rc = false;
	unsigned char* pdata = NULL;
	size_t data_len = 0;

	b_rc = my_ecc_gen_priv_key("ec", "sect571r1", "PEM", pdata, data_len);
	assert(b_rc);

	printf("ec priv key:\n");
	BIO_dump_fp(stdout, pdata, data_len);

	if (NULL != pdata)
	{
		OPENSSL_free(pdata);
		pdata = NULL;
	}
}

bool my_ecc_gen_priv_key(const char* keytype, const char* curve_name, const char* out_format, unsigned char*& pdata, size_t& data_len)
{
	// openssl ecparam -name sect571r1 -genkey -noout -out priv_key_s.pem
	bool b_rc = false;
	OSSL_PARAM _ossl_param_ary[2];
	EVP_PKEY_CTX* _evp_pkey_ctx_key_type = NULL;
	EVP_PKEY* _evp_pkey_key_type = NULL;

	EVP_PKEY_CTX* _evp_pkey_ctx_key = NULL;
	OSSL_ENCODER_CTX* _ossl_encoder_ctx = NULL;
	OSSL_LIB_CTX* _ossl_lib_ctx = NULL;
	
	EVP_PKEY* _evp_pkey = NULL;

	do {
		_ossl_lib_ctx = OSSL_LIB_CTX_new();
		if (NULL == _ossl_lib_ctx)
		{
			break;
		}

		_evp_pkey_ctx_key_type = EVP_PKEY_CTX_new_from_name(_ossl_lib_ctx, keytype, NULL);
		if (NULL == _evp_pkey_ctx_key_type)
		{
			break;
		}

		if (EVP_PKEY_keygen_init(_evp_pkey_ctx_key_type) <= 0)
		{
			break;
		}

		_ossl_param_ary[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, (char*)curve_name, 0);
		_ossl_param_ary[1] = OSSL_PARAM_construct_end();
		if (EVP_PKEY_CTX_set_params(_evp_pkey_ctx_key_type, _ossl_param_ary) <= 0)
		{
			break;
		}

		if (EVP_PKEY_keygen(_evp_pkey_ctx_key_type, &_evp_pkey_key_type) <= 0)
		{
			break;
		}

		_evp_pkey_ctx_key = EVP_PKEY_CTX_new_from_pkey(_ossl_lib_ctx, _evp_pkey_key_type, NULL);
		if (NULL == _evp_pkey_ctx_key)
		{
			break;
		}

		if (EVP_PKEY_keygen_init(_evp_pkey_ctx_key) <= 0)
		{
			break;
		}

		if (EVP_PKEY_keygen(_evp_pkey_ctx_key, &_evp_pkey) <= 0)
		{
			break;
		}

		_ossl_encoder_ctx = OSSL_ENCODER_CTX_new_for_pkey(_evp_pkey, OSSL_KEYMGMT_SELECT_ALL, out_format, NULL, NULL);
		if (NULL == _ossl_encoder_ctx)
		{
			break;
		}

		/*
		int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata, size_t *pdata_len);
		, unsigned char*& pdata, size_t& data_len*/

		if (1 != OSSL_ENCODER_to_data(_ossl_encoder_ctx, &pdata, &data_len))
		{
			break;
		}

		b_rc = true;
	} while (false);

	if (NULL != _ossl_encoder_ctx)
	{
		OSSL_ENCODER_CTX_free(_ossl_encoder_ctx);
		_ossl_encoder_ctx = NULL;
	}

	if (NULL != _evp_pkey)
	{
		EVP_PKEY_free(_evp_pkey);
		_evp_pkey = NULL;
	}

	if (NULL != _evp_pkey_key_type)
	{
		EVP_PKEY_free(_evp_pkey_key_type);
	}

	if (NULL != _evp_pkey_ctx_key_type)
	{
		EVP_PKEY_CTX_free(_evp_pkey_ctx_key_type);
		_evp_pkey_ctx_key_type = NULL;
	}

	if (NULL != _evp_pkey_ctx_key)
	{
		EVP_PKEY_CTX_free(_evp_pkey_ctx_key);
		_evp_pkey_ctx_key = NULL;
	}

	if (NULL != _ossl_lib_ctx)
	{
		OSSL_LIB_CTX_free(_ossl_lib_ctx);
		_ossl_lib_ctx = NULL;
	}

	return b_rc;
}

备注

在网上查的资料, 大概只能参考一下思路. 想找和自己想的一模一样的东西基本不可能.

还是有了思路, 自己从官方实现(权威, 质量有保证)中移植(扒代码)爽.

END

相关推荐
Lazy Dave12 天前
gmssl私钥文件格式
网络安全·ssl·openssl
沉在嵌入式的鱼1 个月前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马1 个月前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin2 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
API开发2 个月前
苹果芯片macOS安装版Homebrew(亲测) ,一键安装node、python、vscode等,比绿色软件还干净、无污染
vscode·python·docker·nodejs·openssl·brew·homebrew
码农不惑2 个月前
Rust使用tokio(二)HTTPS相关
https·rust·web·openssl
liulilittle2 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法并通过OPENSSL加密验证算法正确性。
linux·服务器·c++·算法·安全·加密·openssl
liulilittle2 个月前
OpenSSL 的 AES-NI 支持机制
linux·运维·服务器·算法·加密·openssl·解密
liulilittle2 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法。
linux·服务器·c++·算法·安全·加密·openssl
花花少年2 个月前
Ubuntu系统下交叉编译openssl
openssl·交叉编译