openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_EC_keygen.c

文章目录

    • [openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_EC_keygen.c](#openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_EC_keygen.c)
    • 概述
    • 笔记
    • END

openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_EC_keygen.c

概述

给定椭圆曲线名字, 产生上下文_evp_pkey_ctx

设置_evp_pkey_ctx的椭圆曲线参数(有默认参数, 不用特意设置, 给熟悉的人用), 不熟悉密码学的人, 只选椭圆曲线的名字就行

从_evp_pkey_ctx产生ec key;

打印 ec EVP_PKEY 的值(可以取出椭圆曲线的名字, 公钥, 私钥).

笔记

c 复制代码
/*!
\file EVP_PKEY_EC_keygen.c
\note 
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_EC_keygen.c

给定椭圆曲线名字, 产生上下文_evp_pkey_ctx
设置_evp_pkey_ctx的椭圆曲线参数(有默认参数, 不用特意设置, 给熟悉的人用), 不熟悉密码学的人, 只选椭圆曲线的名字就行
从_evp_pkey_ctx产生ec key;
打印 ec EVP_PKEY 的值(可以取出椭圆曲线的名字, 公钥, 私钥).
*/

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

 /*
  * Example showing how to generate an EC key and extract values from the
  * generated key.
  */

#include <string.h>
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/core_names.h>

#include "my_openSSL_lib.h"

static int get_key_values(EVP_PKEY* pkey);

/*
 * The following code shows how to generate an EC key from a curve name
 * with additional parameters. If only the curve name is required then the
 * simple helper can be used instead i.e. Either
 * pkey = EVP_EC_gen(curvename); OR
 * pkey = EVP_PKEY_Q_keygen(libctx, propq, "EC", curvename);
 */
static EVP_PKEY* do_ec_keygen(void)
{
	/*
	 * The libctx and propq can be set if required, they are included here
	 * to show how they are passed to EVP_PKEY_CTX_new_from_name().
	 */
	OSSL_LIB_CTX* _ossl_lib_ctx = NULL;
	const char* propq = NULL;
	EVP_PKEY* key = NULL;
	OSSL_PARAM _ossl_param[3];
	EVP_PKEY_CTX* _evp_pkey_ctx = NULL;
	const char* curvename = "P-256"; /*! 椭圆曲线的名字 */
	int use_cofactordh = 1;

	_evp_pkey_ctx = EVP_PKEY_CTX_new_from_name(_ossl_lib_ctx, "EC", propq);
	if (_evp_pkey_ctx == NULL) {
		fprintf(stderr, "EVP_PKEY_CTX_new_from_name() failed\n");
		goto cleanup;
	}

	if (EVP_PKEY_keygen_init(_evp_pkey_ctx) <= 0) {
		fprintf(stderr, "EVP_PKEY_keygen_init() failed\n");
		goto cleanup;
	}

	_ossl_param[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
		(char*)curvename, 0);
	/*
	 * This is an optional parameter.
	 * For many curves where the cofactor is 1, setting this has no effect.
	 */
	_ossl_param[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
		&use_cofactordh);
	_ossl_param[2] = OSSL_PARAM_construct_end();
	if (!EVP_PKEY_CTX_set_params(_evp_pkey_ctx, _ossl_param)) {
		fprintf(stderr, "EVP_PKEY_CTX_set_params() failed\n");
		goto cleanup;
	}

	fprintf(stdout, "Generating EC key\n\n");
	if (EVP_PKEY_generate(_evp_pkey_ctx, &key) <= 0) {
		fprintf(stderr, "EVP_PKEY_generate() failed\n");
		goto cleanup;
	}
cleanup:
	EVP_PKEY_CTX_free(_evp_pkey_ctx);
	return key;
}

/*
 * The following code shows how retrieve key data from the generated
 * EC key. See doc/man7/EVP_PKEY-EC.pod for more information.
 *
 * EVP_PKEY_print_private() could also be used to display the values.
 */
static int get_key_values(EVP_PKEY* pkey)
{
	int ret = 0;
	char out_curvename[80];
	unsigned char out_pubkey[80];
	unsigned char out_privkey[80];
	BIGNUM* out_priv = NULL;
	size_t out_pubkey_len, out_privkey_len = 0;

	if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
		out_curvename, sizeof(out_curvename),
		NULL)) {
		fprintf(stderr, "Failed to get curve name\n");
		goto cleanup;
	}

	if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
		out_pubkey, sizeof(out_pubkey),
		&out_pubkey_len)) {
		fprintf(stderr, "Failed to get public key\n");
		goto cleanup;
	}

	if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &out_priv)) {
		fprintf(stderr, "Failed to get private key\n");
		goto cleanup;
	}

	out_privkey_len = BN_bn2bin(out_priv, out_privkey);
	if (out_privkey_len <= 0 || out_privkey_len > sizeof(out_privkey)) {
		fprintf(stderr, "BN_bn2bin failed\n");
		goto cleanup;
	}

	fprintf(stdout, "Curve name: %s\n", out_curvename);
	fprintf(stdout, "Public key:\n");
	BIO_dump_indent_fp(stdout, out_pubkey, (int)out_pubkey_len, 2);
	fprintf(stdout, "Private Key:\n");
	BIO_dump_indent_fp(stdout, out_privkey, (int)out_privkey_len, 2);

	ret = 1;
cleanup:
	/* Zeroize the private key data when we free it */
	BN_clear_free(out_priv);
	return ret;
}

int main(void)
{
	int ret = EXIT_FAILURE;
	EVP_PKEY* _evp_pkey_ec;

	_evp_pkey_ec = do_ec_keygen();
	if (_evp_pkey_ec == NULL)
		goto cleanup;

	if (!get_key_values(_evp_pkey_ec))
		goto cleanup;

	/*
	 * At this point we can write out the generated key using
	 * i2d_PrivateKey() and i2d_PublicKey() if required.
	 */
	ret = EXIT_SUCCESS;
cleanup:
	if (ret != EXIT_SUCCESS)
		ERR_print_errors_fp(stderr);

	EVP_PKEY_free(_evp_pkey_ec);
	return ret;
}

END

相关推荐
Lazy Dave13 天前
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·交叉编译