SM2公私钥生成

调用openssl库实现SM2密钥生成阶段
创建密钥create_key_pair.cpp文件

#include<string.h>
#include<openssl/obj_mac.h>
#include<cstring>
#include<openssl/bn.h>
#include<openssl/ec.h>
#include"create_key_pair.h"
#include"sm2_cipher_error_codes.h"
int create_key_pair(SM2_KEY_PAIR* key_pair_test)
{
	int error_code;
	BN_CTX* ctx = NULL;    //存储大数运算得零时变量
	BIGNUM* bn_d = NULL,* bn_x=NULL,* bn_y=NULL;//bn_d?? ,坐标x,y
	const BIGNUM* bn_order; //阶
	EC_GROUP* group = NULL; //椭圆曲线
	EC_POINT* ec_pt = NULL;//基准坐标点
	unsigned char pub_key_x[32], pub_key_y[32];

	error_code = ALLOCATION_MEMORY_FAIL;  //分配内存空间失败

	if (!(ctx = BN_CTX_secure_new())) //初始化一个BIGNUM结构体
	{                         //BN_CTX_secure_new()动态分配并初始化一个 BIGNUM 结构体。如果执行成功,
		                          //返回值为指向 BIGNUM 结构体的指针,这个 BIGNUM 的值被设为 0。如果执行失败则返回 NULL 。
		goto clear_up;
	}
	BN_CTX_start(ctx);        //如果要获取 BN_CTX 结构体中的临时 BIGNUM 变量,方法如下:
	bn_d = BN_CTX_get(ctx);   //先调用 BN_CTX_start(),再调用 BN_CTX_get() 获取临时 BIGNUM 变量,
	bn_x = BN_CTX_get(ctx);   //可以多次调用 BN_CTX_get(),最后调用 BN_CTX_end()。
	bn_y = BN_CTX_get(ctx);    //调用过 BN_CTX_end() 后 BN_CTX 结构体中的 BIGNUM 变量值将变得无效。
	
	if (!(bn_y))
	{
		goto clear_up;
	}
	if (!(group = EC_GROUP_new_by_curve_name(NID_sm2))) //构建一个内置曲线
	{
		goto clear_up;
	}
	if (!(bn_order = EC_GROUP_get0_order(group)))  //获取阶
	{
		goto clear_up;
	}
	if (!(ec_pt = EC_POINT_new(group)))   //椭圆曲线上得点
	{
		goto clear_up;
	}
	error_code = CREATE_SM2_KEY_PAIR_FAIL;    //创建SM2密钥失败

	do
	{
		if (!(BN_rand_range(bn_d, bn_order)))
		{
			goto clear_up;
		}

	} while (BN_is_zero(bn_d));
	if (!(EC_POINT_mul(group, ec_pt, bn_d, NULL, NULL, ctx)))
	{
		goto clear_up;
	}
	if (!(EC_POINT_get_affine_coordinates_GFp(
		group, ec_pt, bn_x, bn_y, ctx)
		))
	{
		goto clear_up;
	}
	if (BN_bn2binpad(bn_x, pub_key_x, sizeof(pub_key_x)) != sizeof(pub_key_x))
	{
		goto clear_up;
	}
	if (BN_bn2binpad(bn_y, pub_key_y, sizeof(pub_key_y)) != sizeof(pub_key_y))
	{
		goto clear_up;
	}
	key_pair_test->pub_key[0] = 0x4;
	//memccpy((key_pair->pri_key+1),pub_key_x,sizeof(pub_key_x));
	memcpy((key_pair_test->pub_key + 1), pub_key_x, sizeof(pub_key_x));
	memcpy((key_pair_test->pub_key + 1 + sizeof(pub_key_x)), pub_key_y, sizeof(pub_key_y));
	error_code = 0;
clear_up:
	if (ctx)
	{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
	}
	if (group)
	{
		EC_GROUP_free(group);
	}
	if (ec_pt)
	{
		EC_POINT_free(ec_pt);
	}
	return error_code;
}

通过比较error_code = create_key_pair(&key_pair)来判断是否成功生成公私钥对
test_creat_key.cpp文件

#include <stdio.h>
#include <string.h>
#include "create_key_pair.h"
#include <corecrt.h>
#include <corecrt_malloc.h>
int test_create_key(void)
{
	int error_code;
	SM2_KEY_PAIR key_pair;
	int i;

	if (error_code = create_key_pair(&key_pair))
	{
		printf("Create SM2 key pair failed!\n");
		return (-1);
	}
	printf("Create SM2 key pair succeeded!\n");
	printf("Private key:\n");
	for (i = 0; i < sizeof(key_pair.pri_key); i++)
	{
		printf("0x%x  ", key_pair.pri_key[i]);
	}
	printf("\n\n");
	printf("Public key:\n");
	for (i = 0; i < sizeof(key_pair.pub_key); i++)
	{
		printf("0x%x  ", key_pair.pub_key[i]);
	}
	printf("\n\n");

	printf("/*********************************************************/\n");
	return 0;
}

编写主函数test_demo.cpp文件

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<windows.h>
#include "test_create_key.h"
#include"create_key_pair.h"
#include"sm2_cipher_error_codes.h"

using namespace std;
int main(void)
{
	int error_code;
	long t1 = GetTickCount();
	if (error_code = test_create_key())
	{
		printf("Test create SM2 key pair, sign data and verify signature failed!\n");
		return error_code;
	}
	else
	{
		printf("Test create SM2 key pair, sign data and verify signature successed!\n");
	}
	long t2 = GetTickCount();
	cout << "程序执行时间:" <<(t2 - t1)<< endl;
	system("pause");
	return 0;
}

头文件create_key_pair.h

#pragma once
#ifndef HEADER_SM2_CREATE_KEY_PAIR_H
#define HEADER_SM2_CREATE_KEY_PAIR_H

typedef struct sm2_key_pair_structure {
	unsigned char pri_key[64];
	unsigned char pub_key[64];
}SM2_KEY_PAIR;

int create_key_pair(SM2_KEY_PAIR* key_pair);




#endif // !HEADER_SM2_CREATE_KEY_PAIR_H

头文件test_create_key.h

#pragma once
#ifndef HEADER_SM2_SIGN_DATA_AND_VERIFY_SIGNATURE_TEST_H
#define HEADER_SM2_SIGN_DATA_AND_VERIFY_SIGNATURE_TEST_H
#include"create_key_pair.h"
#include"sm2_cipher_error_codes.h"

int test_create_key(void);
#endif

头文件sm2_cipher_error_codes.h

#pragma once
#ifndef HEADER_ERROR_CODES_LIST_OF_SM2_CIPHER_H
#define HEADER_ERROR_CODES_LIST_OF_SM2_CIPHER_H

#define INVALID_NULL_VALUE_INPUT    0x1000
#define INVALID_INPUT_LENGTH        0x1001
#define CREATE_SM2_KEY_PAIR_FAIL    0x1002
#define COMPUTE_SM3_DIGEST_FAIL     0x1003
#define ALLOCATION_MEMORY_FAIL      0x1004
#define COMPUTE_SM2_SIGNATURE_FAIL  0x1005
#define INVALID_SM2_SIGNATURE       0x1006
#define VERIFY_SM2_SIGNATURE_FAIL   0x1007

#endif

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值