使用openssl读取pem文件解析得到公私钥的二进制格式数据

#include "openssl/evp.h"
#include "openssl/pem.h"

bool Key::readDataFromPEMFile(const std::string& filePath)
{
    ifstream fin(filePath, std::fstream::in | std::fstream::binary);
    if (!fin.is_open()) {
        cout << "open file " << filePath << "error." << endl;
        return false;
    }
    unsigned char keyData[1024 * 3] = { 0 };
    unsigned char buf = 0;
    unsigned long totalSize = 0;
    while (fin.read((char*)&buf, 1)) {
        // int cnt_bytes = fin.gcount(); //查看刚才读取了多少字节
        memcpy(keyData + totalSize, &buf, 1);
        totalSize += 1;
    }
    fin.close();

    std::shared_ptr<EC_KEY> ecKey;
    std::shared_ptr<BIO> bioMem(BIO_new(BIO_s_mem()), [&](BIO* p) { BIO_free(p); });
    BIO_write(bioMem.get(), keyData, totalSize);
    std::shared_ptr<EVP_PKEY> evpPKey(PEM_read_bio_PrivateKey(bioMem.get(), NULL, NULL, NULL), [](EVP_PKEY* p) { EVP_PKEY_free(p); });
    if (!evpPKey) {
        cout << "init evpkey failed." << endl;
        return false;
    }
    ecKey.reset(EVP_PKEY_get1_EC_KEY(evpPKey.get()), [](EC_KEY* p) { EC_KEY_free(p); });

    //私钥数据
    std::shared_ptr<const BIGNUM> ecPrivateKey(EC_KEY_get0_private_key(ecKey.get()), [](const BIGNUM*) {});
    unsigned char priOctet[32] = { 0 };
    BN_bn2bin(ecPrivateKey.get(), priOctet);

    //公钥数据
    std::shared_ptr<const EC_GROUP> ecGroup(EC_KEY_get0_group(ecKey.get()), [](const EC_GROUP*) {});
    std::shared_ptr<const EC_POINT> ecPubKey(EC_KEY_get0_public_key(ecKey.get()), [](const EC_POINT*) {});
    unsigned char pubOctet[65] = { 0 };
    EC_POINT_point2oct(ecGroup.get(), ecPubKey.get(), POINT_CONVERSION_UNCOMPRESSED, pubOctet, sizeof(pubOctet), nullptr);

    m_privateKey = std::shared_ptr<const vector<unsigned char>>(new const vector<unsigned char>((unsigned char*)priOctet, (unsigned char*)priOctet + sizeof(priOctet)));
    m_publicKey = std::make_shared<const std::vector<unsigned char>>((unsigned char*)pubOctet + 1, (unsigned char*)pubOctet + sizeof(pubOctet));
    return true;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用OpenSSL库来读取RSA私钥文件,并将其转换为JWK格式。以下是一个简单的示例代码,你可以根据自己的需要进行修改: ```c++ #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/buffer.h> #include <iostream> // 将二进制数据编码为Base64字符串 std::string base64_encode(const unsigned char* input, size_t length) { BIO *bmem = nullptr, *b64 = nullptr; BUF_MEM *bptr = nullptr; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); std::string result(bptr->data, bptr->length - 1); BIO_free_all(b64); return result; } int main() { RSA *rsa = nullptr; EVP_PKEY *pkey = nullptr; std::string private_key_file = "/path/to/private/key/file.pem"; // 读取RSA私钥文件 FILE *fp = fopen(private_key_file.c_str(), "rb"); if (!fp) { std::cerr << "Failed to open private key file." << std::endl; return 1; } rsa = PEM_read_RSAPrivateKey(fp, nullptr, nullptr, nullptr); fclose(fp); if (!rsa) { std::cerr << "Failed to load RSA private key." << std::endl; return 1; } // 将RSA私钥转换为EVP格式 pkey = EVP_PKEY_new(); if (!pkey) { std::cerr << "Failed to create EVP_PKEY object." << std::endl; return 1; } if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) { std::cerr << "Failed to assign RSA to EVP_PKEY." << std::endl; EVP_PKEY_free(pkey); return 1; } // 将EVP格式私钥转换为JWK格式 std::cout << "{"; std::cout << "\"kty\": \"RSA\","; std::cout << "\"n\": \"" << base64_encode(rsa->n->data, rsa->n->length) << "\","; std::cout << "\"e\": \"" << base64_encode(rsa->e->data, rsa->e->length) << "\","; std::cout << "\"d\": \"" << base64_encode(rsa->d->data, rsa->d->length) << "\","; std::cout << "\"p\": \"" << base64_encode(rsa->p->data, rsa->p->length) << "\","; std::cout << "\"q\": \"" << base64_encode(rsa->q->data, rsa->q->length) << "\","; std::cout << "\"dp\": \"" << base64_encode(rsa->dmp1->data, rsa->dmp1->length) << "\","; std::cout << "\"dq\": \"" << base64_encode(rsa->dmq1->data, rsa->dmq1->length) << "\","; std::cout << "\"qi\": \"" << base64_encode(rsa->iqmp->data, rsa->iqmp->length) << "\""; std::cout << "}" << std::endl; // 释放资源 EVP_PKEY_free(pkey); RSA_free(rsa); return 0; } ``` 在上面的代码中,我们首先使用PEM_read_RSAPrivateKey函数从私钥文件读取RSA私钥,然后将其转换为EVP_PKEY格式。最后,我们将EVP_PKEY格式私钥转换为JWK格式,并使用base64_encode函数将二进制数据编码为Base64字符串。 需要注意的是,JWK格式中的各个字段都需要进行Base64编码。在上面的代码中,我们使用了base64_encode函数来实现这一功能。你需要自己实现这个函数或者使用现成的Base64库来完成编码操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值