基于Gmssl的SM2加解密算法Demo

GmSSL介绍

Gmssl介绍:http://gmssl.org/
当然本文也是参考 http://gmssl.org/
其中SM2为非对称算法

SM2密钥生成


pair<string, string> GenKey(void)
{
    EC_KEY *keypair = NULL;
    EC_GROUP *group1 = NULL;

    keypair = EC_KEY_new();
    if(!keypair) {
        cout << "Failed to Gen Key" << endl;
        exit(1);
    }

    group1 = EC_GROUP_new_by_curve_name(NID_sm2p256v1);

    if(group1 == NULL){
        cout << "Failed to Gen Key" << endl;
        exit(1);
    }

    int ret1 = EC_KEY_set_group(keypair, group1);
    if(ret1 != 1){
        cout << "Failed to Gen Key" << endl;
        exit(1);
    }

    int ret2 = EC_KEY_generate_key(keypair);
    if(ret2 != 1){
        cout << "Failed to Gen Key" << endl;
        exit(1);
    }

    size_t pri_len;
    size_t pub_len;
    char *pri_key = NULL;
    char *pub_key = NULL;
 
	BIO *pri = BIO_new(BIO_s_mem());
	BIO *pub = BIO_new(BIO_s_mem());
 
	PEM_write_bio_ECPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
	PEM_write_bio_EC_PUBKEY(pub, keypair);
 
	pri_len = BIO_pending(pri);
	pub_len = BIO_pending(pub);
 
	pri_key = new char[pri_len + 1];
	pub_key = new char[pub_len + 1];
 
	BIO_read(pri, pri_key, pri_len);
	BIO_read(pub, pub_key, pub_len);
 
	pri_key[pri_len] = '\0';
	pub_key[pub_len] = '\0';
 
	string public_key = pub_key;
	string private_key = pri_key;

	EC_KEY_free(keypair);
	BIO_free_all(pub);
	BIO_free_all(pri);
	delete [] pri_key;
	delete [] pub_key;
 
	return std::pair<string, string>(public_key, private_key);
}

已字符串形式的返回,主要考虑我们在实际运用中,可能需要传递密钥信息,所以生成的SM2公钥和私钥以字符串形式返回。

从字符串类型的密钥中生成出来EC_KEY对象

EC_KEY* CreateEC(unsigned char* key, int is_public)
{
	EC_KEY *ec_key = NULL;
	BIO *keybio = NULL;
	keybio = BIO_new_mem_buf(key, -1);
 
	if (keybio==NULL) {
        cout << "Failed to Get Key" << endl;
		exit(1);
	}
 
	if(is_public) {
		ec_key = PEM_read_bio_EC_PUBKEY(keybio, NULL, NULL, NULL);
	}
	else {
		ec_key = PEM_read_bio_ECPrivateKey(keybio, NULL, NULL, NULL);
	}
 
	if(ec_key == NULL) {
        cout << "Failed to Get Key" << endl;
		exit(1);
	}
 
	return ec_key;
}

SM2公钥加密

string Encrypt(const string& public_key, const string& plain_text)
{
	unsigned char encrypted[1024] = {};
 
 	EC_KEY *rsa = CreateEC((unsigned char*)public_key.c_str(), 1);
 	size_t encrypted_length = 1024;
 	int ret = SM2_encrypt_with_recommended((unsigned char*)plain_text.c_str(), plain_text.length(),
    		(unsigned char*)encrypted,&encrypted_length, rsa);

	if (ret == 0) {
        cout << "Failed to Encrypt" << endl;
		exit(1);
	}

	string enc_text((char*)encrypted, encrypted_length);
	return enc_text;
}

这里使用的加密函数为SM2_encrypt_with_recommended

SM2私钥解密

string Decrypt(const string& private_key, const string& enc_text)
{
	unsigned char decrypted[1024] = {};
 
 	EC_KEY * key1 = CreateEC((unsigned char*)private_key.c_str(), 0);

 	size_t decrypted_length = 0;
 	int ret = SM2_decrypt_with_recommended((unsigned char*)enc_text.c_str(), enc_text.length(), decrypted, &decrypted_length, key1);

	if (ret == 0) {
		cout << "Failed to Decrypt" << endl;
		exit(1);
	}

	string plain_text((char*)decrypted, decrypted_length);
	return plain_text;
}

这里使用的解密函数为SM2_decrypt_with_recommended

测试用例代码

下载:https://download.csdn.net/download/liulangaliulang/10884044
用例运行结果:
在这里插入图片描述

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
以下是使用gmssl进行sm2加解密的步骤: 1. 生成密钥对 ```shell # 生成私钥 openssl ecparam -genkey -name sm2p256v1 -out sm2.key # 生成公钥 openssl ec -in sm2.key -pubout -out sm2.pub ``` 2. 使用gmssl进行sm2加密 ```shell # 加密 echo "hello world" > plain.txt gmssl sm2enc -in plain.txt -out cipher.txt sm2.pub ``` 3. 使用gmssl进行sm2解密 ```shell # 解密 gmssl sm2dec -in cipher.txt -out plain2.txt sm2.key ``` 4. 运行结果 ```shell $ cat plain.txt hello world $ cat cipher.txt 30819F300D06092A864886F70D010101050003818D0030818902818100B9C7E5B8B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7B7C5B7

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值