pem 转 SM2用的公钥 C/C++
时间: 2024-03-05 14:49:59 浏览: 18
以下是将PEM格式的SM2公钥转换为C/C++中可以使用的数据结构的示例代码:
```c++
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
/* 将PEM格式的SM2公钥转换为EC_KEY结构 */
EC_KEY *pem_to_ec_key(const char *pem_key) {
EC_KEY *ec_key = NULL;
BIO *bio = NULL;
EVP_PKEY *evp_key = NULL;
bio = BIO_new(BIO_s_mem());
BIO_puts(bio, pem_key);
evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
if (evp_key != NULL) {
ec_key = EVP_PKEY_get1_EC_KEY(evp_key);
EVP_PKEY_free(evp_key);
}
BIO_free(bio);
return ec_key;
}
/* 将EC_KEY结构的SM2公钥转换为C/C++中的数据结构 */
void ec_key_to_bytes(EC_KEY *ec_key, unsigned char *buf, int buf_len) {
const EC_GROUP *group = EC_KEY_get0_group(ec_key);
const EC_POINT *point = EC_KEY_get0_public_key(ec_key);
const EC_POINT *generator = EC_GROUP_get0_generator(group);
const BIGNUM *x = EC_POINT_get0_affine_coordinates_GFp(group, point, NULL, NULL);
const BIGNUM *y = EC_POINT_get0_affine_coordinates_GFp(group, point, x, NULL);
const BIGNUM *order = EC_GROUP_get0_order(group);
const BIGNUM *a = EC_GROUP_get0_a(group);
const BIGNUM *b = EC_GROUP_get0_b(group);
const BIGNUM *gx = EC_POINT_get0_affine_coordinates_GFp(group, generator, NULL, NULL);
const BIGNUM *gy = EC_POINT_get0_affine_coordinates_GFp(group, generator, gx, NULL);
int len = BN_num_bytes(order);
if (buf_len < len * 6) {
return;
}
memset(buf, 0, buf_len);
buf[0] = len * 2 + 1;
buf[1] = 0x02;
BN_bn2bin(x, buf + 2 + len - BN_num_bytes(x));
buf[len + 2] = 0x03;
BN_bn2bin(y, buf + len + 3 + len - BN_num_bytes(y));
buf[len * 2 + 3] = len;
BN_bn2bin(order, buf + len * 2 + 4);
BN_bn2bin(a, buf + len * 3 + 4);
BN_bn2bin(b, buf + len * 4 + 4);
buf[len * 5 + 4] = len * 2;
BN_bn2bin(gx, buf + len * 5 + 5 + len - BN_num_bytes(gx));
BN_bn2bin(gy, buf + len * 6 + 5 + len - BN_num_bytes(gy));
}
/* 示例用法 */
int main() {
const char *pem_key = "-----BEGIN PUBLIC KEY-----\n"
"MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEyKmZGn1LbXtjJ0Gj4Fg6IhXzgHd\n"
"qz5M5zgAvoU+OeGQ0FmLjSw5zUyvJfE8vJx42vZIYdJ1s0j3w/h5lQ+MzA==\n"
"-----END PUBLIC KEY-----\n";
EC_KEY *ec_key = pem_to_ec_key(pem_key);
if (ec_key != NULL) {
int len = EC_GROUP_get_degree(EC_KEY_get0_group(ec_key)) / 8;
unsigned char buf[len * 6 + 5];
ec_key_to_bytes(ec_key, buf, sizeof(buf));
/* buf中存储了C/C++中的SM2公钥 */
EC_KEY_free(ec_key);
}
return 0;
}
```
其中,`pem_to_ec_key`函数将PEM格式的SM2公钥转换为EC_KEY结构,`ec_key_to_bytes`函数将EC_KEY结构的SM2公钥转换为C/C++中的数据结构。在示例代码中,C/C++中的SM2公钥存储在`buf`中。