RSA_public_encrypt 出现分段错误

getting a segmentation fault with RSA_public_encrypt

这是我的代码:

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <string.h>

int main (void)
{
        char publicKey[] = "-----BEGIN RSA PUBLIC KEY-----\n"\
"MIIBCgKCAQEAqBa0jeqfHO8CFZuHyN5WgdTd3uThkU/I9lR+bb2R9khVU1tYhiyL\n"\
"Gfnm051K0039gCBAz9S7HHO2lqR/B1kiEGwBzg83N3tL2UzQXXbpxJz0b7vV8rXZ\n"\
"fB9j+FCAtD5znittXRjWrNqlEyJyxK+PuxNF3uPGWSjkYtRKv2f5HCXsfRJah40w\n"\
"5zU+OKZsZMrSSxweYN9Jwc++oMaSPCsGKog6NPbkbcTK8Akveof8v5rpG50I/zcQ\n"\
"9dCD69qJcmhm4ai4fAZFJlsFH2HmxV6DERFs3TNyzGlSQ1gd/XLER7U9nlrOUT87\n"\
"mXreUIXSkAFdCrlHXHOzj0eodfN8IfHjnQIDAQAB\n"\
"-----END RSA PUBLIC KEY-----\n";
    char plaintext[] = "enp6";

    // base64 decode plaintext
    EVP_DecodeBlock(plaintext, plaintext, strlen(plaintext));

    BIO* bo = BIO_new(BIO_s_mem());
    BIO_write(bo, publicKey, strlen(publicKey));
    EVP_PKEY* pkey = 0;
    PEM_read_bio_PUBKEY(bo, NULL, NULL, NULL);
    BIO_free(bo);
    RSA* rsa = EVP_PKEY_get1_RSA(pkey);
    char ciphertext[RSA_size(rsa)];

    RSA_public_encrypt(strlen(plaintext), plaintext, ciphertext, rsa, RSA_NO_PADDING);
    printf("%d\n", (int) strlen(ciphertext));
}

我正尝试通过 gcc -x c test2.c -lcrypto && ./a.out 来 运行 它。关于我做错了什么有什么想法吗?

您的代码包含多个错误。段错误的直接原因是变量 pkey 在用 0 初始化后从未被赋值。 EVP_PKEY_get1_RSA(pkey) 结果是段错误。你可能打算做

EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bo, NULL, NULL, NULL);

但是,对于您发布的 PEM,这将不起作用。 PEM 的 header 表示这是一个以“传统”格式存储的 RSA 密钥。 PEM_read_bio_RSAPublicKey 能够读取这样的键:

RSA *rsa = PEM_read_bio_RSAPublicKey(bo, NULL, NULL, NULL);

那你调用RSA_public_encrypt时选择的RSA_NO_PADDING是不对的。为了使用它,明文的长度必须与密钥大小完全相同。您可以尝试改用 RSA_PKCS1_PADDING

最后,正如评论区所说,密文使用strlen是不正确的,因为它不是以0结尾的字符串。

一般来说,您应该检查所有调用的 OpenSSL 函数的所有 return 值,以查看 when/if 出了什么问题。