RSA公钥
openssl默认生成的RSA公钥为pem格式的,即公钥数据进行der编码再经过BASE64编码再加上头和尾的表示组成的。获取公钥原始数据,需要对秘钥进行base64解码,即可以获得der编码格式的公钥。通常RSA公钥的e为65537 二进制01 00 01 ,RSA公钥中的随机大数n为固定64,128,256等长度字节,对。, 为RSA密钥中epem公钥解码获取公钥数据代码如下:
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <string.h>
#include <iostream>
std::string rsaPubKeyStr="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPx62Myb/H8p4JND8bds5Z9EqFuAyQfj8DC8WJDZ4fHX42ZYqhUxfxHzI/KkoFR3CxpFH2XMfvb2m3BMzQ238jQPutpqJFYpqCgRIZmRuqlpsbkOtCv7yZjVTym3VK0sNOGHv3SXmNyfzuMHRxnD6rgZZB+zq/ukaZm+1FIhlQswIDAQAB";
int rsaKeyPem2Hex(std::string publicKeyStr,unsigned char* publicKeyHex)
{
//creater public key
for(int i = 64; i < publicKeyStr.size(); i+=64)
{
if(publicKeyStr[i] != '\n')
{
publicKeyStr.insert(i, "\n");
}
++i;
}
publicKeyStr.insert(0, "-----BEGIN PUBLIC KEY-----\n");
publicKeyStr.append("\n-----END PUBLIC KEY-----\n");
RSA *p_rsa;
BIO* pubBp = NULL;
std::string temPubKeyStr =publicKeyStr;
std::cout<<"publicKeyStr: "<<std::endl<<publicKeyStr<<std::endl;
//creaete pub key
char *chPublicKey = const_cast<char *>(temPubKeyStr.c_str());
if ((pubBp = BIO_new_mem_buf(chPublicKey, -1)) == NULL)
{
printf("BIO_new_mem_buf failed!\n");
}
p_rsa = PEM_read_bio_RSA_PUBKEY(pubBp, NULL, NULL, NULL);
BIO_free_all(pubBp);
if (NULL == p_rsa)
{
ERR_load_crypto_strings();
char errBuf[512];
ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
printf("load RSA public key failed[%s]\n", errBuf);
}
//pem 2 hex
unsigned char* p_rsa_hex=new unsigned char[512];
unsigned char* temp_rsa_hex=p_rsa_hex;
char buf[3];
std::string reuslt;
// int len=i2d_RSA_PUBKEY(p_rsa,&p_rsa_hex);//提取der编码公钥
//提取公钥中的n
ASN1_INTEGER* n=BN_to_ASN1_INTEGER( RSA_get0_n(p_rsa),nullptr);
int len=i2d_ASN1_INTEGER(n,&p_rsa_hex);
memset(publicKeyHex,0,512);
memcpy(publicKeyHex,temp_rsa_hex+4,len-4);
//print
printf("len : %d \n",len);
printf("p_rsa_hex: \n");
for (int i = 0; i < len; i++)
{
printf("0x%x ", temp_rsa_hex[i]);
sprintf(buf,"%02x",temp_rsa_hex[i]);
reuslt+=buf;
}
printf("\n");
std::cout<<"result:"<<reuslt;
return len;
}
int main(int argc, char *argv[])
{
unsigned char rsaKeyhex[512];
int rsaLen=rsaKeyPem2Hex(rsaPubKeyStr,rsaKeyhex);
}
SM2公钥
SM2公钥通常以前缀04开头,后跟两个256位数字;一个用于点的x坐标,另一个用于点的y坐标。前缀04用于区分未压缩的公共密钥和以02或03开头的压缩公共密钥,即04||x||y。opeenssl生成的公钥为pem格式的。转化为SM2pem公钥为16进制数据,为1+64字节数据。
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/x509.h>
#include <string.h>
#include <iostream>
std::string sm2PubKeyStr="MIIBMzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/v8AAAAA//8wRAQg/v8AAAAA//wEICjp+p6dn140TVqeS89lCafzl4n1FauPkt28vUFNlA6TBEEEMsSuLB8ZgRlfmQRGajnJlI/jC7/yZgvhcVpFiTNMdMe8Nzai9PZ3nFm9zuNraSFT0KmHfMYqR0AC3zLlITnwoAIhAP7///9yA99rIcYFK1O79Ak51UEjAgEBA0IABDyeGRqnvwPDODAacgE1+Bc0jKio/N9P6ueZe9Ens1jx+M42KqX3BBjGWLK4CKXqU27ZrHYxQugbjeR0oTxrYlQ=";
int sm2KeyPem2Hex(std::string publicKeyStr,unsigned char* publicKeyHex)
{
//creater publickey
for(int i = 64; i < publicKeyStr.size(); i+=64)
{
if(publicKeyStr[i] != '\n')
{
publicKeyStr.insert(i, "\n");
}
++i;
}
publicKeyStr.insert(0, "-----BEGIN PUBLIC KEY-----\n");
publicKeyStr.append("\n-----END PUBLIC KEY-----\n");
EVP_PKEY * Sm2PubKey;
BIO* pubBp = NULL;
std::cout<<"publicKeyStr: "<<publicKeyStr<<std::endl;
//creaete pub key
char *chPublicKey = const_cast<char *>(publicKeyStr.c_str());
if ((pubBp = BIO_new_mem_buf(chPublicKey, -1)) == NULL)
{
printf("BIO_new_mem_buf failed!\n");
}
Sm2PubKey = PEM_read_bio_PUBKEY(pubBp, NULL, NULL, NULL);
BIO_free_all(pubBp);
if (NULL == Sm2PubKey)
{
ERR_load_crypto_strings();
char errBuf[512];
ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
printf("load sm2 public key failed[%s]\n", errBuf);
}
//pem 2 hex
unsigned char* p_sm2_hex=new unsigned char[512];
unsigned char* temp_sm2_hex=p_sm2_hex;
char buf[3];
std::string reuslt;
int len=i2d_PublicKey(Sm2PubKey,&p_sm2_hex);
printf("len: %d \n",len);
printf("p_sm2_hex: \n");
for (int i = 0; i < len; i++)
{
printf("0x%x ", temp_sm2_hex[i]);
sprintf(buf,"%02x",temp_sm2_hex[i]);
reuslt+=buf;
}
printf("\n");
printf("sizeof(reuslt):%d \n",reuslt.size());
std::cout<<"result:"<<reuslt;
memset(publicKeyHex,0,128);
memcpy(publicKeyHex,temp_sm2_hex+1,len-1);
return len-1;
}