简体   繁体   English

如何将 X509 证书转换为 C++ 中的公钥字符串?

[英]How to convert an X509 certificate to a public key string in C++?

I'm new to OpenSSL and cryptography in general, and I've been stuck at this for a few hours.我是 OpenSSL 和密码学的新手,我已经坚持了几个小时。 I have an x5c certificate chain from here ( https://login.microsoftonline.com/common/discovery/keys ) and I'm trying to convert it to a public key so that I can validate a JWT token (in C++).我有一个来自这里的 x5c 证书链 ( https://login.microsoftonline.com/common/discovery/keys ),我正在尝试将其转换为公钥,以便我可以验证 JWT 令牌(在 C++ 中)。

I was able to do it on the command line by pasting the x5c certificate with a "-----BEGIN CERTIFICATE------" and end certificate before and after the certificate and calling我可以通过在命令行上粘贴带有“-----BEGIN CERTIFICATE------”的 x5c 证书并在证书前后结束证书并调用来完成此操作

openssl x509 -in cert -pubkey -noout > public-key openssl x509 -in cert -pubkey -noout > 公钥

where cert is "-----BEGIN CERTIFICATE----- MIIDBTCCAe2gAwIBAgIQdEMOjSqDVbdN3mzb2IumCzANBgkqhkiG9w0BAQsFADAt MSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4X DTE5MDYwNDAwMDAwMFoXDTIxMDYwNDAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3Vu dHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAKEUUBvom99MdPXlrQ6S9MFmoQPoYI3NJVqEFOJcARY11dj3 zyJogL8MTsTRt+DIJ8NyvYbgWC7K7zkAGzHQZhPJcM/AxSjFqh6qB98UqgxoSGBa G0A4lUZJHnKW3qx+YaiWrkg+z4sAwUkP0QgyI29Ejpkk6WUfe1rOJNc/defFUX+A VGxo81beLVAM/8tnCOSbF0H3IADwd76D/Hrp8RsGf4jPHr8N4VDsO/p7oj8rbOx0 pL1ehjMK13zspmP8NO5mMcP9i5yiJ37FgbXESAxvja7I9t+y4LQYSu05M7la4Lqv //m5A8MBd6k0VxgF/Sq8GOIbkcQ0bJTCIN9B6oMCAwEAAaMhMB8wHQYDVR0OBBYE FNRP0Lf6MDeL11RDH0uL7H+/JqtLMA0GCSqGSIb3DQEBCwUAA4IBAQCJKR1nxp9I j/yisCmDG7bdN1yHj/2HdVvyLfCCyReRfkB3cnTZVaIOBy5occGkdmsYJ+q8uqcz koCMAz3gvvq1c0msKEiNpqWNeU2aRXqyL3QZJ/GBmUK1I0tINPVv8j7znm0DcvHH XFvhzS8E4s8ai8vQkcpyac/7Z4PN43HtjDnkZo9Zxm7JahHshrhA8sSPvsuC4dQA cHbOrLbHG+HIo3Tq2pNl7mfQ9fVJ2FxbqlzPYr/rK8H2GTA其中CERT为“----- BEGIN CERTIFICATE ----- MIIDBTCCAe2gAwIBAgIQdEMOjSqDVbdN3mzb2IumCzANBgkqhkiG9w0BAQsFADAt MSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4X DTE5MDYwNDAwMDAwMFoXDTIxMDYwNDAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3Vu dHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAKEUUBvom99MdPXlrQ6S9MFmoQPoYI3NJVqEFOJcARY11dj3 zyJogL8MTsTRt + DIJ8NyvYbgWC7K7zkAGzHQZhPJcM / AxSjFqh6qB98UqgxoSGBa G0A4lUZJHnKW3qx + YaiWrkg + z4sAwUkP0QgyI29Ejpkk6WUfe1rOJNc / defFUX + A VGxo81beLVAM / 8tnCOSbF0H3IADwd76D / Hrp8RsGf4jPHr8N4VDsO / p7oj8rbOx0 pL1ehjMK13zspmP8NO5mMcP9i5yiJ37FgbXESAxvja7I9t + y4LQYSu05M7la4Lqv // m5A8MBd6k0VxgF / Sq8GOIbkcQ0bJTCIN9B6oMCAwEAAaMhMB8wHQYDVR0OBBYE FNRP0Lf6MDeL11RDH0uL7H + / JqtLMA0GCSqGSIb3DQEBCwUAA4IBAQCJKR1nxp9I焦耳/ yisCmDG7bdN1yHj / 2HdVvyLfCCyReRfkB3cnTZVaIOBy5occGkdmsYJ + q8uqcz koCMAz3gvvq1c0msKEiNpqWNeU2aRXqyL3QZJ / GBmUK1I0tINPVv8j7znm0DcvHH XFvhzS8E4s8ai8vQkcpyac / 7Z4PN43HtjDnkZo9Zxm7JahHshrhA8sSPvsuC4dQA cHbOrLbHG + HIo3Tq2pNl7mfQ9fVJ2FxbqlzPYr / rK8H2GTA 6N55SuP3KTNvyL3Rn Ma3hXmGTdG1dpMFzD/IE623h/BqY6j29PyQC/+MUD4UCZ6KW9oIzpi27pKQagH1i 1jpBU/ceH6AW -----END CERTIFICATE-----" 6N55SuP3KTNvyL3Rn Ma3hXmGTdG1dpMFzD/IE623h/BqY6j29PyQC/+MUD4UCZ6KW9oIzpi27pKQagH1i 1jpBU/ceH6AW -----结束证书-----》

I've been trying to do this in C++ with the following:我一直在尝试在 C++ 中使用以下方法执行此操作:

    BIO *b = BIO_new(BIO_s_mem());
    BIO_puts(b, cert); //cert is a byte array with the certificate contents from above
X509 * x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
EVP_PKEY *pkey = X509_get_pubkey(x509);
auto eckey = EVP_PKEY_get1_EC_KEY(pkey);
auto ecpoint = EC_KEY_get0_public_key(eckey);
size_t public_key_hex_size;
unsigned char* public_key_oct;

EC_GROUP *ec_group = NULL;
ec_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
BN_CTX *bn_ctx = BN_CTX_new();
public_key_hex_size = EC_POINT_point2oct(ec_group, ecpoint, POINT_CONVERSION_COMPRESSED, NULL, 0, bn_ctx);



public_key_oct = (unsigned char *)OPENSSL_malloc(public_key_hex_size);

But then it says x509 is null, so I'm not sure how to correctly read it in from a byte array.但是然后它说 x509 为空,所以我不确定如何从字节数组中正确读取它。

Figured it out!弄清楚了!

Here's the code for anyone who has a similar question.这是任何有类似问题的人的代码。

std::string x5c_to_public_key(const std::string& x5c) {
    BIO_ptr output_bio(BIO_new(BIO_s_mem()), BIO_free);
    BIO_reset(output_bio.get());
    std::string cert_data(x5c);
    boost::erase_all(cert_data, "-----BEGIN CERTIFICATE-----");
    boost::erase_all(cert_data, "-----END CERTIFICATE-----");
    if (boost::contains(cert_data, "\t")) {
        boost::replace_all(cert_data, "\t", " ");
    }
    boost::trim_all(cert_data);
    boost::replace_all(cert_data, " ", "\n");
    std::vector<std::string> vec;
    vec.push_back("-----BEGIN CERTIFICATE-----");
    vec.push_back(cert_data);
    vec.push_back("-----END CERTIFICATE-----");

    std::string szCertData = boost::algorithm::join(vec, "\n");
    BIO * bio = BIO_new(BIO_s_mem());
    BIO_puts(bio, szCertData.c_str());

    X509 * clientCert;
    clientCert = PEM_read_bio_X509(bio, NULL, 0, NULL);

    //length is the length of the certificateDataBytes in terms of bytes.
    //cert4 = d2i_X509(NULL, (const unsigned char **)&certy, 1091);
    //pubkey = X509_get_pubkey(cert4);
    EVP_PKEY *pkey = X509_get_pubkey(clientCert);
    //EVP_PKEY_print_public(output_bio.get(), pkey, 0, NULL);
    PEM_write_bio_PUBKEY(output_bio.get(), pkey);

    return bio_to_string(output_bio, 40000); // don't hardcode this
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM