OpenSSL 3.1.1 ECC 加密、解密、签名、验签(国密 sm2、sm3)
openssl 3 默认废弃了 旧版本 (opessl 1.x) 的部分api 导致部分旧ecc 代码无法使用(可以通过配置编译选项打开)
,这里展示如何使用新接口用ECC 进行加密解密。
新接口是真的方便,基本上你都不需要懂啥密码学知识,对我们这种密码白痴来说太好了
头文件
生成密钥对
导出公钥&导入公钥
公钥加密
私钥解密
私钥签名
公钥验签
工具函数
所有代码(后来改过)文章来源:https://www.toymoban.com/news/detail-755046.html
头文件
小小的封装了一下文章来源地址https://www.toymoban.com/news/detail-755046.html
#include "openssl/crypto.h"
#include "openssl/types.h"
#include "openssl/x509.h"
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
class sm2PrivateKey;
struct EVP_CUNSTOM{
EVP_PKEY * pkey=NULL;
~EVP_CUNSTOM(){
if(pkey!=NULL){
EVP_PKEY_free(pkey);
}
}
};
class sm2PublicKey{
public:
sm2PublicKey()=default;
sm2PublicKey(const sm2PublicKey & other){
m_pkey=other.m_pkey;
}
sm2PublicKey(const std::string & pub_str);
sm2PublicKey(const unsigned char * pub_str,size_t len);
std::string Encrypt(const std::string & message,std::string & error);
bool SignatureVerification(const std::string & signature,const std::string & message,std::string & error);
std::string GetPublicString();
std::string GetPublicStringBase64();
private:
std::shared_ptr<EVP_CUNSTOM> m_pkey=nullptr;//使用shared_ptr 防止拷贝构造的时候造成内存泄漏和意外释放
};
class sm2PrivateKey{
public:
sm2PrivateKey();
sm2PrivateKey(const std::string & priv_str);
sm2PublicKey CreatePublic();
std::string Decrypt(const std::string & encoded,std::string & error);
std::string Signature(const std::string & message ,std::string & error);
std::string GetPrivateString();
private:
std::shared_ptr<EVP_CUNSTOM> M_PKEY=nullptr;
};
生成密钥对
sm2PrivateKey::sm2PrivateKey(){
EVP_PKEY *ret = NULL;
EVP_PKEY_CTX *pkctx = NULL;
pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL);//创建sm2 上下文
if(pkctx==NULL){
errorL("EVP_PKEY_CTX_new_id");
return;
}
int retV=1;
retV=EVP_PKEY_keygen_init(pkctx);//初始化sm2 上下文
if (retV <= 0) {
errorL("EVP_PKEY_keygen_init:" << GetErrorStr());
EVP_PKEY_CTX_free(pkctx);
return ;
}
retV=EVP_PKEY_keygen(pkctx, &ret);//生成密钥对
if (retV <= 0) {
errorL("EVP_PKEY_keygen:" << GetErrorStr());
EVP_PKEY_CTX_free(pkctx);
return ;
}
EVP_CUNSTOM * cst=new EVP_CUNSTOM{ret};
M_PKEY=std::shared_ptr<EVP_CUNSTOM>(cst);
EVP_PKEY_CTX_free(pkctx);
}
导出公钥和导入公钥
sm2PublicKey sm2PrivateKey::CreatePublic(){
unsigned char *buffer=nullptr;
int retV=i2d_PUBKEY(M_PKEY.get()->pkey, &buffer);//导出
if (retV <= 0) {
errorL("i2d_PUBKEY:" <<GetErrorStr());
return sm2PublicKey{};
}
//buffer 里的是公钥二进制
sm2PublicKey pub(buffer,retV);
//OPENSSL_free(buffer);
return pub;
}
sm2PublicKey::sm2PublicKey(const unsigned char * pub_str,size_t len){
EVP_PKEY * pkey_t=NULL;
//pkey_t=d2i_PublicKey(EVP_PKEY_SM2,NULL, &pub_str, len);
pkey_t=d2i_PUBKEY(NULL, &pub_str, len);//导入
std::string error;
if(pkey_t==NULL){
error=GetErrorStr();
errorL(error);
return;
}
EVP_CUNSTOM *cst=new EVP_CUNSTOM{pkey_t};
m_pkey=std::shared_ptr<EVP_CUNSTOM>(cst);
}
公钥加密
std::string sm2PublicKey::Encrypt(const std::string &message,std::string &error) {
std::string encodedstr;
EVP_PKEY_CTX *pkctx = NULL;
int retV=1;
if (!(pkctx = EVP_PKEY_CTX_new(m_pkey.get()->pkey, NULL))) {//生成上下文
error=GetErrorStr();
errorL("EVP_PKEY_CTX_new:" << error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV=EVP_PKEY_encrypt_init(pkctx);//加密初始化
if (retV <= 0) {
error=GetErrorStr();
errorL("EVP_PKEY_encrypt_init:" <<error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
size_t outbuflen=0;
unsigned char * outbuf=NULL;
retV=EVP_PKEY_encrypt(pkctx, NULL, &outbuflen,
(const unsigned char *)message.c_str(), message.size());//加密 (传NULL 仅获取密文长度)
if (retV <= 0) {
error=GetErrorStr();
errorL("EVP_PKEY_encrypt:" << error );
EVP_PKEY_CTX_free(pkctx);
return "";
}
if(outbuflen==0){
errorL("EVP_PKEY_encrypt:" << "no memery");
EVP_PKEY_CTX_free(pkctx);
return "";
}
outbuf=new unsigned char[outbuflen];
retV=EVP_PKEY_encrypt(pkctx, outbuf, &outbuflen,
(const unsigned char *)message.c_str(), message.size());//加密
if (retV <= 0) {
error=GetErrorStr();
errorL("EVP_PKEY_encrypt:" << error );
EVP_PKEY_CTX_free(pkctx);
delete[] outbuf;
return "";
}
encodedstr=std::string((const char *)outbuf,outbuflen);//获取结果
delete[] outbuf;
EVP_PKEY_CTX_free(pkctx);
return encodedstr;
}
私钥解密
std::string sm2PrivateKey::Decrypt(const std::string &encoded,
std::string &error) {
std::string decodedstr;
EVP_PKEY_CTX *pkctx = NULL;
unsigned char * outbuf=NULL;
size_t outlen=0;
int retV = 1;
if (!(pkctx = EVP_PKEY_CTX_new(M_PKEY.get()->pkey, NULL))) {//创建EVP 上下文
error = GetErrorStr();
errorL("EVP_PKEY_CTX_new:" << error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV = EVP_PKEY_decrypt_init(pkctx);// 解密初始化
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_decrypt_init:" << error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV=EVP_PKEY_decrypt(pkctx, NULL, &outlen,
(const unsigned char *)encoded.c_str(), encoded.size());//解密
if(retV<=0){
error = GetErrorStr();
errorL("EVP_PKEY_encrypt_init:" << error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
if(outlen==0){
errorL("EVP_PKEY_decrypt:" << error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
outbuf=new unsigned char[outlen];
retV=EVP_PKEY_decrypt(pkctx, outbuf, &outlen,
(const unsigned char *)encoded.c_str(), encoded.size());//解密
if(retV<=0){
error = GetErrorStr();
errorL("EVP_PKEY_encrypt_init:" << error);
EVP_PKEY_CTX_free(pkctx);
delete[] outbuf;
return "";
}
decodedstr=std::string((const char *)outbuf,outlen);
delete[] outbuf;
EVP_PKEY_CTX_free(pkctx);
return decodedstr;
}
私钥签名
std::string sm2PrivateKey::Signature(const std::string & message ,std::string & error){
std::string signatured;
EVP_MD_CTX *mdctx = NULL;
unsigned char * outbuf=NULL;
size_t outbuflen=0;
int retV=0;
if(!(mdctx = EVP_MD_CTX_create())){//创建摘要上下文
error=GetErrorStr();
errorL("EVP_MD_CTX_create:" << error);
return "";
}
retV=EVP_DigestSignInit(mdctx, NULL, EVP_sm3(),//使用sm3 摘要算法
NULL, M_PKEY.get()->pkey);//签名初始化
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignInit:" << error);
EVP_MD_CTX_free(mdctx);
return "";
}
retV=EVP_DigestSignUpdate(mdctx, message.c_str(), message.size());//更新签名内容
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignUpdate:" << error);
EVP_MD_CTX_free(mdctx);
return "";
}
retV= EVP_DigestSignFinal(mdctx, NULL, &outbuflen);//获取签名长度
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignFinal:" << error);
EVP_MD_CTX_free(mdctx);
return "";
}
outbuf=new unsigned char[outbuflen];
retV= EVP_DigestSignFinal(mdctx, outbuf, &outbuflen);//获取签名结果
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignFinal:" << error);
EVP_MD_CTX_free(mdctx);
return "";
}
signatured=std::string((const char *)outbuf,outbuflen);
delete[] outbuf;
return signatured;
}
公钥验签
bool sm2PublicKey::SignatureVerification(const std::string &signature, const std::string &message, std::string &error){
std::string signatured;
EVP_MD_CTX *mdctx = NULL;
int retV=0;
if(!(mdctx = EVP_MD_CTX_create())){//创建摘要上下文
error=GetErrorStr();
errorL("EVP_MD_CTX_create:" << error);
return false;
}
retV=EVP_DigestVerifyInit(mdctx, NULL, EVP_sm3(), NULL, m_pkey.get()->pkey);//验签初始化
if(retV <=0){
error=GetErrorStr();
errorL("EVP_DigestVerifyInit:" << error);
EVP_MD_CTX_free(mdctx);
return false;
}
retV=EVP_DigestVerifyUpdate(mdctx, message.c_str() , message.size());//更新验签内容
if(retV <=0){
error=GetErrorStr();
EVP_MD_CTX_free(mdctx);
errorL("EVP_DigestVerifyUpdate:" << error);
return false;
}
retV=EVP_DigestVerifyFinal(mdctx, (const unsigned char *)signature.c_str(), signature.size());//验证签名
if(retV <=0){
error=GetErrorStr();
EVP_MD_CTX_free(mdctx);
errorL("EVP_DigestVerifyFinal:" << error);
return false;
}
EVP_MD_CTX_free(mdctx);
return true;
}
工具函数
#define RED_t "\033[31m"
#define YELLOW_t "\033[33m"
#define GREEN_t "\033[32m"
#define WRITE "\033[0m"
#define errorL(msg) \
std::cout << RED_t <<"Error:["<< __FILE__ << ":"<< __LINE__ << "]:"<< msg << WRITE <<std::endl;
#define debugL(msg) \
std::cout << YELLOW_t <<"debug:["<< __FILE__ << ":"<< __LINE__ << "]:"<< msg << WRITE << std::endl;
#define infoL(msg) \
std::cout << GREEN_t <<"infor:["<< __FILE__ << ":" << __LINE__ << "]:"<< msg << WRITE << std::endl;
std::string GetErrorStr(){
unsigned long er=0;
char erbuf[512]={0};
size_t erlen=512;
er=ERR_get_error();
ERR_error_string_n(er,erbuf,erlen);
return std::string(erbuf,erlen);
}
所有代码
// ssl.h
#include <openssl/types.h>
#include <cstddef>
#include <memory>
#ifndef _MY_SSL_
#include <openssl/evp.h>
#include <string>
class sm2PrivateKey;
struct EVP_CUNSTOM {
EVP_PKEY* pkey = NULL;
~EVP_CUNSTOM() {
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
}
};
class sm2PublicKey {
public:
sm2PublicKey() = default;
sm2PublicKey(const sm2PublicKey& other) {
m_pkey = other.m_pkey;
}
sm2PublicKey(const std::string& pub_str);
sm2PublicKey(const unsigned char* pub_str, size_t len);
std::string Encrypt(const std::string& message, std::string& error);
bool SignatureVerification32(const std::string& signature, const std::string& message, std::string& error);
bool SignatureVerification(const std::string& signature, const std::string& message, std::string& error);
std::string GetPublicString();
private:
std::shared_ptr<EVP_CUNSTOM> m_pkey = nullptr;
};
class sm2PrivateKey {
public:
sm2PrivateKey();
static sm2PrivateKey CreateWithPEM(const std::string& pem);
sm2PublicKey CreatePublic();
std::string GetPEM();
std::string Decrypt(const std::string& encoded, std::string& error);
std::string Signature32(const std::string& message, std::string& error);
std::string Signature(const std::string& message, std::string& error);
private:
sm2PrivateKey(EVP_CUNSTOM* st) {
if (st == nullptr) {
return;
}
M_PKEY = std::shared_ptr<EVP_CUNSTOM>(st);
}
std::shared_ptr<EVP_CUNSTOM> M_PKEY = nullptr;
};
//ssl.cpp
#include "ssl.h"
#include <openssl/crypto.h>
#include <openssl/types.h>
#include <openssl/x509.h>
#include <cstddef>
#include <cstring>
#include "debug.h"
#include <memory>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <string>
std::string GetErrorStr() {
unsigned long er = 0;
char erbuf[512] = { 0 };
size_t erlen = 512;
er = ERR_get_error();
ERR_error_string_n(er, erbuf, erlen);
return std::string(erbuf, erlen);
}
sm2PublicKey::sm2PublicKey(const unsigned char* pub_str, size_t len) {
EVP_PKEY* pkey_t = NULL;
pkey_t = d2i_PUBKEY(NULL, &pub_str, len);
std::string error;
if (pkey_t == NULL) {
error = GetErrorStr();
errorL(error);
return;
}
EVP_CUNSTOM* cst = new EVP_CUNSTOM{ pkey_t };
m_pkey = std::shared_ptr<EVP_CUNSTOM>(cst);
}
sm2PublicKey::sm2PublicKey(const std::string& pub_str) {
EVP_PKEY* pkey_t = NULL;
unsigned char* c_str = new unsigned char[pub_str.size()];
memcpy(c_str, (const void*)pub_str.c_str(), pub_str.size());
pkey_t = d2i_PUBKEY(NULL, (const unsigned char**)&c_str, pub_str.size());
std::string error;
if (pkey_t == NULL) {
error = GetErrorStr();
errorL(error);
return;
}
EVP_CUNSTOM* cst = new EVP_CUNSTOM{ pkey_t };
m_pkey = std::shared_ptr<EVP_CUNSTOM>(cst);
delete[] c_str;
}
std::string sm2PublicKey::Encrypt(const std::string& message,
std::string& error) {
std::string encodedstr;
EVP_PKEY_CTX* pkctx = NULL;
int retV = 1;
if (!(pkctx = EVP_PKEY_CTX_new(m_pkey.get()->pkey, NULL))) {
error = GetErrorStr();
errorL("EVP_PKEY_CTX_new:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV = EVP_PKEY_encrypt_init(pkctx);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_encrypt_init:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
size_t outbuflen = 0;
unsigned char* outbuf = NULL;
retV = EVP_PKEY_encrypt(pkctx, NULL, &outbuflen,
(const unsigned char*)message.c_str(),
message.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_encrypt:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
if (outbuflen == 0) {
errorL("EVP_PKEY_encrypt:%s", "no memery");
EVP_PKEY_CTX_free(pkctx);
return "";
}
outbuf = new unsigned char[outbuflen];
retV = EVP_PKEY_encrypt(pkctx, outbuf, &outbuflen,
(const unsigned char*)message.c_str(),
message.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_encrypt:%s", error);
EVP_PKEY_CTX_free(pkctx);
delete[] outbuf;
return "";
}
encodedstr = std::string((const char*)outbuf, outbuflen);
delete[] outbuf;
EVP_PKEY_CTX_free(pkctx);
return encodedstr;
}
bool sm2PublicKey::SignatureVerification32(const std::string& signature,
const std::string& message,
std::string& error) {
EVP_PKEY_CTX* pkctx = NULL;
unsigned char* outbuf = NULL;
size_t outlen = 0;
int retV = 1;
if (!(pkctx = EVP_PKEY_CTX_new(m_pkey.get()->pkey, NULL))) {
error = GetErrorStr();
errorL("EVP_PKEY_CTX_new:%s", error);
EVP_PKEY_CTX_free(pkctx);
return false;
}
retV = EVP_PKEY_verify_init(pkctx);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_verify_init:%s", error);
EVP_PKEY_CTX_free(pkctx);
return false;
}
retV = EVP_PKEY_verify(
pkctx, (const unsigned char*)signature.c_str(), signature.size(),
(const unsigned char*)message.c_str(), message.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_sign:%s", error);
EVP_PKEY_CTX_free(pkctx);
return false;
}
EVP_PKEY_CTX_free(pkctx);
return true;
}
bool sm2PublicKey::SignatureVerification(const std::string& signature,
const std::string& message,
std::string& error) {
std::string signatured;
EVP_MD_CTX* mdctx = NULL;
int retV = 0;
if (!(mdctx = EVP_MD_CTX_create())) {
error = GetErrorStr();
errorL("EVP_MD_CTX_create:%s", error);
return false;
}
retV =
EVP_DigestVerifyInit(mdctx, NULL, EVP_sm3(), NULL, m_pkey.get()->pkey);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestVerifyInit:%s", error);
EVP_MD_CTX_free(mdctx);
return false;
}
retV = EVP_DigestVerifyUpdate(mdctx, message.c_str(), message.size());
if (retV <= 0) {
error = GetErrorStr();
EVP_MD_CTX_free(mdctx);
errorL("EVP_DigestVerifyUpdate:%s", error);
return false;
}
retV = EVP_DigestVerifyFinal(
mdctx, (const unsigned char*)signature.c_str(), signature.size());
if (retV <= 0) {
error = GetErrorStr();
EVP_MD_CTX_free(mdctx);
errorL("EVP_DigestVerifyFinal:%s", error);
return false;
}
EVP_MD_CTX_free(mdctx);
return true;
}
std::string sm2PublicKey::GetPublicString() {
unsigned char* buffer = nullptr;
int retV = i2d_PUBKEY(m_pkey.get()->pkey, &buffer);
if (retV <= 0) {
errorL("i2d_PUBKEY:%s", GetErrorStr());
return "";
}
std::string ret((const char*)buffer, retV);
OPENSSL_free(buffer);
return ret;
}
sm2PrivateKey::sm2PrivateKey() {
EVP_PKEY* ret = NULL;
EVP_PKEY_CTX* pkctx = NULL;
pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL);
if (pkctx == NULL) {
errorL("EVP_PKEY_CTX_new_id");
return;
}
int retV = 1;
retV = EVP_PKEY_keygen_init(pkctx);
if (retV <= 0) {
errorL("EVP_PKEY_keygen_init:%s", GetErrorStr());
EVP_PKEY_CTX_free(pkctx);
return;
}
retV = EVP_PKEY_keygen(pkctx, &ret);
if (retV <= 0) {
errorL("EVP_PKEY_keygen:%s", GetErrorStr());
EVP_PKEY_CTX_free(pkctx);
return;
}
EVP_CUNSTOM* cst = new EVP_CUNSTOM{ ret };
M_PKEY = std::shared_ptr<EVP_CUNSTOM>(cst);
EVP_PKEY_CTX_free(pkctx);
}
sm2PrivateKey sm2PrivateKey::CreateWithPEM(const std::string& pem)
{
EVP_PKEY* pkey = nullptr;
BIO* bio = BIO_new_mem_buf((const void*)pem.c_str(), pem.size());
if (bio == nullptr) {
errorL("BIO_new_mem_buf error!");
BIO_free(bio);
}
pkey = PEM_read_bio_PrivateKey(bio, NULL, 0, NULL);
if (!pkey) {
errorL("PEM_read_bio_PrivateKey error!");
}
BIO_free(bio);
EVP_CUNSTOM* cst = new EVP_CUNSTOM{ pkey };
return sm2PrivateKey(cst);
}
sm2PublicKey sm2PrivateKey::CreatePublic() {
unsigned char* buffer = nullptr;
int retV = i2d_PUBKEY(M_PKEY.get()->pkey, &buffer);
if (retV <= 0) {
errorL("i2d_PUBKEY:%s", GetErrorStr());
return sm2PublicKey{};
}
sm2PublicKey pub(buffer, retV);
OPENSSL_free(buffer);
return pub;
}
std::string sm2PrivateKey::GetPEM()
{
BIO* bio = BIO_new(BIO_s_mem());
if (bio == nullptr) {
errorL("BIO_new_mem_buf error!");
BIO_free(bio);
return "";
}
if (1 != PEM_write_bio_PrivateKey(bio, M_PKEY->pkey, NULL, NULL, 0, NULL, NULL)) {
errorL("PEM_write_bio_PrivateKey error!");
BIO_free(bio);
return "";
}
BUF_MEM* bptr;
BIO_get_mem_ptr(bio, &bptr);
BIO_set_close(bio, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */
BIO_free(bio);
std::string ret(bptr->data, bptr->length);
BUF_MEM_free(bptr);
return ret;
}
std::string sm2PrivateKey::Decrypt(const std::string& encoded,
std::string& error) {
std::string decodedstr;
EVP_PKEY_CTX* pkctx = NULL;
unsigned char* outbuf = NULL;
size_t outlen = 0;
int retV = 1;
if (!(pkctx = EVP_PKEY_CTX_new(M_PKEY.get()->pkey, NULL))) {
error = GetErrorStr();
errorL("EVP_PKEY_CTX_new:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV = EVP_PKEY_decrypt_init(pkctx);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_decrypt_init:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV = EVP_PKEY_decrypt(pkctx, NULL, &outlen,
(const unsigned char*)encoded.c_str(),
encoded.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_encrypt_init:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
if (outlen == 0) {
errorL("EVP_PKEY_decrypt:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
outbuf = new unsigned char[outlen];
retV = EVP_PKEY_decrypt(pkctx, outbuf, &outlen,
(const unsigned char*)encoded.c_str(),
encoded.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_encrypt_init:%s", error);
EVP_PKEY_CTX_free(pkctx);
delete[] outbuf;
return "";
}
decodedstr = std::string((const char*)outbuf, outlen);
delete[] outbuf;
EVP_PKEY_CTX_free(pkctx);
return decodedstr;
}
std::string sm2PrivateKey::Signature32(const std::string& message,
std::string& error) {
std::string signatured;
EVP_PKEY_CTX* pkctx = NULL;
unsigned char* outbuf = NULL;
size_t outlen = 0;
int retV = 1;
if (message.size() != 32) {
error = "size not eq 32";
return "";
}
if (!(pkctx = EVP_PKEY_CTX_new(M_PKEY.get()->pkey, NULL))) {
error = GetErrorStr();
errorL("EVP_PKEY_CTX_new:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
retV = EVP_PKEY_sign_init(pkctx);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_sign_init:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
debugL("msglen:%s", message.size());
retV =
EVP_PKEY_sign(pkctx, NULL, &outlen,
(const unsigned char*)message.c_str(), message.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_sign:%s", error);
EVP_PKEY_CTX_free(pkctx);
return "";
}
debugL(outlen);
outbuf = new unsigned char[outlen];
retV =
EVP_PKEY_sign(pkctx, outbuf, &outlen,
(const unsigned char*)message.c_str(), message.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_PKEY_sign:%s", error);
EVP_PKEY_CTX_free(pkctx);
delete[] outbuf;
return "";
}
signatured = std::string((const char*)outbuf, outlen);
EVP_PKEY_CTX_free(pkctx);
return signatured;
}
std::string sm2PrivateKey::Signature(const std::string& message,
std::string& error) {
std::string signatured;
EVP_MD_CTX* mdctx = NULL;
unsigned char* outbuf = NULL;
size_t outbuflen = 0;
int retV = 0;
if (!(mdctx = EVP_MD_CTX_create())) {
error = GetErrorStr();
errorL("EVP_MD_CTX_create:%s", error);
return "";
}
retV = EVP_DigestSignInit(mdctx, NULL, EVP_sm3(), NULL, M_PKEY.get()->pkey);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignInit:%s", error);
EVP_MD_CTX_free(mdctx);
return "";
}
retV = EVP_DigestSignUpdate(mdctx, message.c_str(), message.size());
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignUpdate:%s", error);
EVP_MD_CTX_free(mdctx);
return "";
}
retV = EVP_DigestSignFinal(mdctx, NULL, &outbuflen);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignFinal:%s", error);
EVP_MD_CTX_free(mdctx);
return "";
}
outbuf = new unsigned char[outbuflen];
retV = EVP_DigestSignFinal(mdctx, outbuf, &outbuflen);
if (retV <= 0) {
error = GetErrorStr();
errorL("EVP_DigestSignFinal:%s", error);
EVP_MD_CTX_free(mdctx);
return "";
}
signatured = std::string((const char*)outbuf, outbuflen);
delete[] outbuf;
return signatured;
}
#endif
到了这里,关于OpenSSL 3.1.1 ECC 加密、解密、签名、验签(国密 sm2、sm3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!