使用OpenSSL的EVP_KEY获取RSA原始私钥失败求助
问题分析与解决方案
核心问题
你的代码存在三个关键错误,导致私钥无法正确获取和打印:
错误使用
EVP_PKEY_get_raw_private_key
该函数仅支持EC、Ed25519等算法的"原始私钥"格式,RSA私钥是ASN.1 DER编码的结构化数据,无法通过此函数提取。调用该函数会直接失败(返回0),因此private_key数组始终未被写入。内存分配长度错误
RSA私钥的DER编码长度远大于KEY_LENGTH(1024位RSA的DER私钥约1KB),你用KEY_LENGTH +1分配的内存完全不足,且未先查询实际所需长度。二进制数据用字符串方式打印
私钥是二进制字节序列,包含大量不可打印字符和0值字节,用printf("%s")会在第一个0字节处截断,无法完整输出。
修正后的代码
方案1:输出PEM格式私钥(最常用,可读性强)
直接通过OpenSSL的PEM函数将私钥输出为Base64编码的文本格式:
#include <openssl/evp.h> #include <openssl/pem.h> #include <stdio.h> #include <stdlib.h> #define KEY_LENGTH 1024 int main() { EVP_PKEY *pkey = EVP_RSA_gen(KEY_LENGTH); if (pkey == NULL) { fprintf(stderr, "error: rsa gen\n"); ERR_print_errors_fp(stderr); return 1; } // 输出PEM格式私钥到标准输出 if (!PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL)) { fprintf(stderr, "error: write private key\n"); ERR_print_errors_fp(stderr); EVP_PKEY_free(pkey); return 1; } EVP_PKEY_free(pkey); return 0; }
方案2:获取DER编码二进制私钥并以十六进制打印
若需获取原始二进制私钥并查看,先查询长度再分配内存,最后以十六进制格式打印:
#include <openssl/evp.h> #include <openssl/asn1.h> #include <stdio.h> #include <stdlib.h> #define KEY_LENGTH 1024 int main() { EVP_PKEY *pkey = EVP_RSA_gen(KEY_LENGTH); if (pkey == NULL) { fprintf(stderr, "error: rsa gen\n"); ERR_print_errors_fp(stderr); return 1; } // 第一步:获取DER编码私钥的长度 int pkey_len = i2d_PrivateKey(pkey, NULL); if (pkey_len <= 0) { fprintf(stderr, "error: get private key length\n"); ERR_print_errors_fp(stderr); EVP_PKEY_free(pkey); return 1; } // 分配内存 unsigned char *private_key = malloc(pkey_len); if (!private_key) { fprintf(stderr, "error: malloc failed\n"); EVP_PKEY_free(pkey); return 1; } // 第二步:将私钥编码到内存中 unsigned char *ptr = private_key; i2d_PrivateKey(pkey, &ptr); // 以十六进制打印私钥 printf("DER私钥(十六进制):\n"); for (int i = 0; i < pkey_len; i++) { printf("%02x ", private_key[i]); if ((i + 1) % 16 == 0) printf("\n"); } printf("\n"); free(private_key); EVP_PKEY_free(pkey); return 0; }
额外注意事项
- 所有OpenSSL函数调用必须检查返回值,比如
EVP_PKEY_get_raw_private_key返回0表示失败,你之前未做错误检查,导致无法发现函数调用失败的问题。 - 记得释放
EVP_PKEY和分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Vladouch
相关产品推荐
相关产品推荐

