openssl公钥格式转换

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;
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值