sm2 gmssl C语言实现验签
时间: 2023-09-20 17:13:59 浏览: 121
C语言实现的SM2数字签名验证
以下是使用 gmssl 库中的 sm2 签名验签的 C 语言代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/sm2.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
int main(void) {
int ret = 0;
EVP_PKEY *pkey = NULL;
EC_KEY *ec_key = NULL;
const EVP_MD *digest = NULL;
unsigned char message[] = "hello world";
unsigned char signature[] = {
0x30, 0x44, 0x02, 0x20, 0x04, 0x8b, 0x56, 0x45, 0x42, 0x32, 0x95, 0x53, 0x7c, 0x57, 0x20, 0x15,
0x12, 0x3e, 0x52, 0x71, 0x9d, 0x4d, 0x3d, 0x2c, 0x1a, 0x8d, 0x1d, 0x2b, 0xb8, 0x59, 0x1d, 0x1b,
0xa2, 0x02, 0x20, 0x2b, 0x63, 0x8a, 0x49, 0x06, 0x9c, 0x8e, 0xd1, 0x70, 0x9a, 0x5d, 0xf2, 0x0c,
0x4d, 0x4f, 0x90, 0x4f, 0xa6, 0x0f, 0x9b, 0x11, 0x7d, 0x86, 0x23, 0x7e, 0x9b, 0x2e, 0x7e, 0x0b,
0xef, 0x79, 0x3d, 0x1e, 0x01,
};
size_t message_len = strlen((const char *)message);
size_t signature_len = sizeof(signature);
unsigned char pub_key[65] = {
0x04, 0xd2, 0x11, 0x80, 0x8a, 0x8e, 0x6f, 0x0c, 0x34, 0x03, 0xbb, 0x31, 0x4d, 0x8f, 0x7f, 0x8c,
0x76, 0xe5, 0x9f, 0x6e, 0xbc, 0x18, 0x43, 0x2e, 0x87, 0x56, 0x7f, 0x80, 0x3d, 0x77, 0x2e, 0x3a,
0x6d, 0x5f, 0x7b, 0x93, 0xf6, 0x3b, 0x62, 0xc3, 0x4d, 0x1a, 0x35, 0x58, 0x11, 0x0c, 0x3e, 0xa0,
0x90, 0x3b, 0x1b, 0x06, 0x00, 0x8b, 0x23, 0x7c, 0x26, 0x3b, 0x8e, 0xcd, 0x18, 0x48, 0x18, 0xf3,
};
size_t pub_key_len = sizeof(pub_key);
// 初始化 gmssl 库
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
// 读取公钥
ec_key = EC_KEY_new_by_curve_name(NID_sm2);
if (ec_key == NULL) {
ret = -1;
goto end;
}
EC_KEY_set_public_key_affine_coordinates(ec_key, pub_key + 1, pub_key + 1 + 32);
pkey = EVP_PKEY_new();
if (pkey == NULL) {
ret = -1;
goto end;
}
EVP_PKEY_set1_EC_KEY(pkey, ec_key);
// 验证签名
digest = EVP_sm3();
ret = SM2_verify(NID_sm3, message, message_len, signature, signature_len, pkey);
if (ret == 1) {
printf("signature verified successfully!\n");
} else {
printf("signature verification failed!\n");
}
end:
// 释放资源
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
if (ec_key != NULL) {
EC_KEY_free(ec_key);
}
EVP_cleanup();
ERR_free_strings();
return ret;
}
```
需要注意的是,上述代码中的 `message`、`signature` 和 `pub_key` 都是示例数据,实际使用时需要替换成实际数据。同时,也需要在编译时链接上 gmssl 库,例如:
```
gcc -o sm2_verify sm2_verify.c -lgmssl
```
阅读全文