C openssl SM2 消息签名
以下是使用 OpenSSL 库进行 SM2 消息签名的示例代码:
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/sm2.h>
void handleErrors(void)
{
printf("Error occurred.\n");
ERR_print_errors_fp(stderr);
abort();
}
int sm2_sign(const unsigned char *msg, size_t msglen, const EC_KEY *key, unsigned char *sig, unsigned int *siglen)
{
EVP_MD_CTX *mdctx = NULL;
const EVP_MD *md = NULL;
int ret = 0;
if (!msg || !msglen || !key || !sig || !siglen)
{
printf("Invalid input.\n");
return -1;
}
md = EVP_sm3();
mdctx = EVP_MD_CTX_new();
if (!mdctx)
{
printf("Failed to create MD context.\n");
handleErrors();
}
if (!EVP_DigestInit_ex(mdctx, md, NULL))
{
printf("Failed to initialize digest.\n");
handleErrors();
}
if (!EVP_DigestUpdate(mdctx, msg, msglen))
{
printf("Failed to update digest.\n");
handleErrors();
}
size_t siglen_tmp = *siglen;
ret = ECDSA_sign(EVP_PKEY_SM2, EVP_sm3(), EVP_MD_CTX_md(mdctx), EVP_MD_CTX_md_size(mdctx), (unsigned char *)msg, msglen, sig, &siglen_tmp, (EC_KEY *)key);
if (ret != 1)
{
printf("Failed to sign message.\n");
handleErrors();
}
*siglen = siglen_tmp;
EVP_MD_CTX_free(mdctx);
return 0;
}
int main(void)
{
EC_KEY *key = NULL;
unsigned char message[] = "Hello, SM2!";
size_t message_len = strlen((const char *)message);
unsigned char signature[SM2_MAX_SIGNATURE_SIZE] = {0};
unsigned int signature_len = SM2_MAX_SIGNATURE_SIZE;
// Load private key from file or generate a new one
key = EC_KEY_new_by_curve_name(NID_sm2);
if (!EC_KEY_generate_key(key))
{
printf("Failed to generate key.\n");
handleErrors();
}
// Sign message using private key
if (sm2_sign(message, message_len, key, signature, &signature_len) != 0)
{
printf("Failed to sign message.\n");
handleErrors();
}
// Print signature
printf("Signature: ");
for (int i = 0; i < signature_len; i++)
{
printf("%02x", signature[i]);
}
printf("\n");
// Verify signature using public key
if (ECDSA_verify(EVP_PKEY_SM2, EVP_sm3(), message, message_len, signature, signature_len, key) != 1)
{
printf("Failed to verify signature.\n");
handleErrors();
}
else
{
printf("Signature verified successfully.\n");
}
// Free resources
EC_KEY_free(key);
return 0;
}
该示例代码使用 EVP_SM3() 函数计算消息的 SM3 摘要,并使用 ECDSA_sign() 函数对摘要进行签名。签名后,可以使用 ECDSA_verify() 函数使用公钥验证签名。请注意,公钥必须与用于签名的私钥相对应。
在运行此代码之前,您需要确保已正确安装 OpenSSL 库并将其包含在项目中。请注意,SM2 签名需要 OpenSSL 1.1.1 或更高版本
原文地址: https://www.cveoy.top/t/topic/cKNe 著作权归作者所有。请勿转载和采集!