使用OPENSSL实现SM2生成PEM格式公私钥对并用于签名验签:
操作系统:centos7.9
openssl版本:v1.1.1u
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <string.h>
// 全局变量,存储公私钥对的 PEM 格式数据
char *publicKeyPEM = NULL;
char *privateKeyPEM = NULL;
// 辅助函数,用于从 EC_KEY 转换为 EVP_PKEY
EVP_PKEY *EC_KEY_to_EVP_PKEY(EC_KEY *ec_key) {
EVP_PKEY *pkey = EVP_PKEY_new();
if (!pkey) {
fprintf(stderr, "Error: Failed to create EVP_PKEY.\n");
return NULL;
}
if (!EVP_PKEY_set1_EC_KEY(pkey, ec_key)) {
EVP_PKEY_free(pkey);
fprintf(stderr, "Error: Failed to set EVP_PKEY with EC_KEY.\n");
return NULL;
}
return pkey;
}
int SM2_sign(const char *sourcefilename, const char *sigfilename) {
int ret = 0;
// 从全局变量中获取私钥
BIO *bio_mem = BIO_new(BIO_s_mem());
BIO_write(bio_mem, privateKeyPEM, strlen(privateKeyPEM));
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio_mem, NULL, NULL, NULL);
BIO_free_all(bio_mem);
if (pkey == NULL) {
fprintf(stderr, "Error: Unable to read private key from global variable.\n");
return -1;
}
/* compute SM2 signature */
EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
EVP_MD_CTX_set_pkey_ctx(mctx, ctx);
ret = EVP_DigestSignInit(mctx, NULL, EVP_sm3(), NULL, pkey);