以下是使用 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 或更高版本

C openssl SM2 消息签名

原文地址: https://www.cveoy.top/t/topic/cKNe 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录