c++ PEM_read_bio_PUBKEY返回空指针

wljmcqd8  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(363)

我将在下面附上我的完整代码以及一个示例运行。简而言之,这是失败的:

EVP_PKEY * pk = PEM_read_bio_PUBKEY(bioReadPublic, nullptr, nullptr, nullptr);

如果我从互联网上找到的例子中剪切并粘贴一个公钥,它就可以工作。所以我认为这个错误与我产生密钥的方式有关。但是我可以很好地使用私钥(或者至少我认为我可以)。
当我cout它们时,公钥和私钥看起来都没问题。
有人知道我哪里做错了吗?
代码在这里,然后运行一个示例。

#include <iostream>
#include <iostream>

#include <openssl/bio.h>
#include <openssl/pem.h>

using std::cout;
using std::cerr;
using std::endl;
using std::string;

int main()
{
    ::RSA * rsa = nullptr;
    ::BIGNUM * bne = nullptr;
    ::BIO * bioPrivate = nullptr;
    ::BIO * bioPublic = nullptr;
    ::BIO * bioReadPublic = nullptr;
    ::BIO * bioReadPrivate = nullptr;
    ::RSA * privateRSA = nullptr;
    ::RSA * publicRSA = nullptr;

    int bits = 2048;

    try {
        // This code produces the public/private keys.
        rsa = RSA_new();
        bne = BN_new();
        BN_set_word(bne, RSA_F4);
        RSA_generate_key_ex(rsa, bits, bne, NULL);

        bioPrivate = BIO_new( BIO_s_mem() );
        bioPublic = BIO_new( BIO_s_mem() );
        PEM_write_bio_RSAPrivateKey( bioPrivate, rsa, nullptr, nullptr, 0, nullptr, nullptr );
        PEM_write_bio_RSAPublicKey( bioPublic, rsa );

        size_t privateLen = BIO_pending( bioPrivate );
        size_t publicLen = BIO_pending( bioPublic );

        // Oversized.
        char privateBuffer[10000];
        char publicBuffer[10000];

        BIO_read(bioPrivate, privateBuffer, privateLen);
        BIO_read(bioPublic, publicBuffer, publicLen);

        privateBuffer[privateLen] = 0;
        publicBuffer[publicLen] = 0;

        string privateKey = privateBuffer;
        string publicKey = publicBuffer;

        cout << "Keys:\n"
             << privateKey << endl << endl
             << publicKey << endl << endl;

        // And this is where I try to use them.

        cout << "Try PEM_read\n";
        bioReadPrivate = BIO_new_mem_buf( (void *)privateBuffer, privateLen );
        bioReadPublic = BIO_new_mem_buf( (void *)publicBuffer, publicLen );

        cout << "The private...\n";
        privateRSA = PEM_read_bio_RSAPrivateKey(bioReadPrivate, nullptr, nullptr, nullptr);
        if (privateRSA == nullptr) {
            cout << "Failed to read private key\n";
        }

        cout << "The public...\n";
        publicRSA = PEM_read_bio_RSAPublicKey(bioReadPublic, nullptr, nullptr, nullptr);
        if (publicRSA == nullptr) {
            cout << "Failed to read public key\n";
        }

        EVP_PKEY * pk = PEM_read_bio_PUBKEY(bioReadPublic, nullptr, nullptr, nullptr);
        if (pk == nullptr) {
            cout << "PEM_read_bio_PUBKEY failed\n";
        }
    }
    catch (const std::exception &e) {
        cerr << "Exception: " << e.what() << endl;
    }

    cout << "Done.\n";

    if (privateRSA != nullptr) {
        RSA_free(privateRSA);
    }
    if (publicRSA != nullptr) {
        RSA_free(publicRSA);
    }
    if (bioReadPrivate != nullptr) {
        BIO_free(bioReadPrivate);
    }
    if (bioReadPublic != nullptr) {
        BIO_free(bioReadPublic);
    }
    if (bioPublic != nullptr) {
        BIO_free(bioPublic);
    }
    if (bioPrivate != nullptr) {
        BIO_free(bioPrivate);
    }
    if (bne != nullptr) {
        BN_free(bne);
    }
    if (rsa != nullptr) {
        RSA_free(rsa);
    }
    return 0;
}

运行它将生成以下输出:

Keys:
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEArqd1UmR+VYPByNJujunS5FhlkSgsuxiSTjWJCdNoUkdIcKxJ
6ZvNV6uQAkJdL3RgHBRmhrb2CBTkkYdJoB0HyY58AgTH25eJpW7aRmHMh6exzrSv
47MkKVuHVfLNw/RjA3cTDMMgg5SHg4bS8O9lXa9A3YIAUtTb3f4xhuYX8ZG64SzB
lhCruCRKubb1N7eSuqLpq8DJqMj842PEwEU5HfQhxWHU4KAK43Wkglq6BjkKYULR
0/cUm8hMK5WE63LJ0mSsU4sD9UdzpbPD1WO+KBPLX6C0O/z6fGmEIwEyjNmXomUE
tqOBhW+1tEvF9T/l5UF/a+RyQs4uPjqsuiBfrQIDAQABAoIBAH6FqSQK0Mo6LIPC
jXzSPohU0R8ar2zKHBK0DZYkpAoWwY99//1PdK3yBtzcHo1mDMnKrYsht5GbMQmL
q/ZlkWKd6Y+8zttxJ7HEYDNkXbpX7SMFGfYlrCiZuay1vAIcZC36cL5qDH/FdXX+
kYkgo5n+f0r4Biv7L1vd7RsATJAeAla8wz+SQ5TVyONMQ4KYvQFk4GrIOtkdvVjW
B+EMxNPRFdLBpGL0cAwwEMS71H30R+NqOogRWpok/gE4LTe3tohoNMr9UvRrQucG
xLLUMLlQFe+t2iys1oRLRbIsPbp8+Jb0LkPnEuz+rG86nyg5UnTyI2KSkW5GO2sP
1l+xUDECgYEA55JVMSOeQWFBfh1MySbOsbceGT/0ZPmrOEj0n2Sab59iJv/9B/W0
SlZ+nmZzDq7Zxkefaaq2+1uaqHzPstqJUPAuCvJV4dJ1dMX3gAhVxMiIyPR4KywZ
Wq22r7hWOggwQ8nt7YLhbXX0NG9MepHUpbYniGBH04y/Ff4kV/yMkKcCgYEAwRQM
5KZa2GNjcqRH+G+/DyjSml8cyv/HyA/bp5hsRUZJdNnuHK0Dl07IED31d3r023Mz
vBgwqZ0DNnfNvqebrtkeQE2MBgXBU5r8lZ/Xc1uzC5ClYxvjAMvR/GW9XpatqvZa
+tw/DeQ08htwc/yvKAlJwnp3AQRmDQyVwG+hI4sCgYAc7MBLZQGNdRJzKEHBFmHW
/OJ7kOt7+VuTqjkz96L6slPWPz9h0ST17BvguTdB7EEzbRrSXgqBFw4YYY6n7ngc
bgOyRlbH4DvfnCKwEVp1O/8p6q9f5SA9nVkmVcYfdYphzUU015ZEz+jy67wHy1Ne
Z4REmpIeMIRlwNrVSqxcHQKBgF3DMOew6Zj/2wGHSfQZwDzKZEvXOJJUWF6NZOwk
lx+lHHMEih+e3YmTFpDcpeHZ8iLH9S24yZj0yOSglWeq2W21vn0Xq5IZJWNGdrbq
oqRAudg57DcPCdQPJvBdL/NJVRka/d+pKW3Djvqr3JZW9XCJ4inxcu0ph616mRaU
nzo1AoGAbSMgdhMRq1x78LhI4zHklyonA55T5eO3Tk+tyXF513e9LmVTgVg6sCsj
pU+4/gMHa3oDn+LU1LsxuJU+xn/zHVFTjIYaw8+dLzHv7mVz3DpdeAVud3BRuHNu
kj7X7ZsRRCtGv8762B5YOdbAlXStc6i2JHLyWI1n7s324hm1f3c=
-----END RSA PRIVATE KEY-----

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEArqd1UmR+VYPByNJujunS5FhlkSgsuxiSTjWJCdNoUkdIcKxJ6ZvN
V6uQAkJdL3RgHBRmhrb2CBTkkYdJoB0HyY58AgTH25eJpW7aRmHMh6exzrSv47Mk
KVuHVfLNw/RjA3cTDMMgg5SHg4bS8O9lXa9A3YIAUtTb3f4xhuYX8ZG64SzBlhCr
uCRKubb1N7eSuqLpq8DJqMj842PEwEU5HfQhxWHU4KAK43Wkglq6BjkKYULR0/cU
m8hMK5WE63LJ0mSsU4sD9UdzpbPD1WO+KBPLX6C0O/z6fGmEIwEyjNmXomUEtqOB
hW+1tEvF9T/l5UF/a+RyQs4uPjqsuiBfrQIDAQAB
-----END RSA PUBLIC KEY-----

Try PEM_read
The private...
The public...
PEM_read_bio_PUBKEY failed
Done.
vyu0f0g1

vyu0f0g11#

好吧,这归结为一行代码。
我使用的底层JWT库是这样做的:

EVP_PKEY * pk = PEM_read_bio_PUBKEY(bioReadPublic, nullptr, nullptr, nullptr);

这意味着我的公钥需要与之兼容,所以我不使用PEM_write_bio_RSAPublicKey,而是像这样使用PEM_write_bio_RSA_PUBKEY

PEM_write_bio_RSA_PUBKEY( bioPublic, rsa );

生成的数据有很小的不同。公钥看起来像这样:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoMeN556vV68LEAQ1KE22
n6fHTCsVV1CwKMo8L6WvCMD13xNs72MwA+FNNOZUTg2+2HvaH7ZnwNgLPeY/O+Rc
vTBLI90qGxAubGYnvp+76hNROzXQfLFlTQdGiu2vF0oiCU00EDKM4xzL8iOf7H8A
aw9f6S0Y9UiaZAMJ0CLXwv6yWLvxHgNGiJ1Z3VGrUnW16K9EGyoNMYARPiJqSMaG
Grw26SUBzA485zzZfiIgnruriuiBQPp9dL5vvGAvRFODCcj45Jqpo25hTSADQTw3
kUUQ5WRRy2Din1VAEWJflCUMAf+VowODoglZP5YOSkf8lsBlVpekroWNFVaQehs3
MwIDAQAB
-----END PUBLIC KEY-----

如果你回到我最初的帖子,你会发现格式只是略有不同。开始RSA PUBLIC KEY vs BEGIN PUBLIC KEY。我不知道是否还有更多的不同,因为当然每次我运行它,它都会生成新的密钥,我没有进一步研究。

相关问题