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 出了什么问题。
这是我的代码:
#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 出了什么问题。