OpenSSL读取EC密钥后重新写入结果不一致,求技术建议
问题根源分析
你的判断方向完全正确!核心问题出在密钥格式差异上:
- 你生成的原始密钥是SEC1格式的EC专属私钥(以
-----BEGIN EC PRIVATE KEY-----开头) - 而通用的
PEM_write_bio_PrivateKey函数默认会输出PKCS#8格式的通用私钥(以-----BEGIN PRIVATE KEY-----开头)
虽然两种格式包含的密钥核心信息是等价的,但文本表现完全不同,这就是你看到输出和原密钥不一致的原因。你给EC_KEY设置的OPENSSL_EC_NAMED_CURVE标志是正确的,但它只影响密钥的ASN.1编码是否包含曲线名称,无法改变PEM_write_bio_PrivateKey的默认输出格式。
解决方案:直接写入EC_KEY
最简洁的解决方法是使用OpenSSL专门为EC私钥设计的写入函数PEM_write_bio_ECPrivateKey,跳过通用EVP_PKEY接口,直接输出和原始密钥一致的SEC1格式。
修改你的getPrivateKeyAsPEM函数如下:
std::string getPrivateKeyAsPEM() { if (!ecKey) { throw std::runtime_error("error3"); } BIO* outbio = BIO_new(BIO_s_mem()); // 使用EC专属PEM写入函数,确保输出SEC1格式的EC私钥 if (!PEM_write_bio_ECPrivateKey(outbio, ecKey, NULL, NULL, 0, 0, NULL)) { BIO_free(outbio); // 出错时也要释放资源避免泄漏 throw std::runtime_error("error4"); } std::string keyStr; int priKeyLen = BIO_pending(outbio); keyStr.resize(priKeyLen); BIO_read(outbio, (void*)&(keyStr.front()), priKeyLen); BIO_free(outbio); // 释放BIO资源 return keyStr; }
额外优化建议
- 修复资源泄漏:原代码中创建的
BIO、EVP_PKEY、EC_KEY都没有释放,建议添加清理逻辑:
int main() { // ... 原有代码 ... // 程序结束时清理资源 if (ecKey) EC_KEY_free(ecKey); if (pkey) EVP_PKEY_free(pkey); return 0; }
同时在setPrivateKeyFromPEM函数中,使用完BIO后也要调用BIO_free(bio);。
- 曲线标志的同步(可选):如果坚持要用
EVP_PKEY接口写入,需要确保EVP_PKEY关联的EC_KEY已设置OPENSSL_EC_NAMED_CURVE,并通过PEM_write_bio_PrivateKey的扩展参数指定格式,但这种方式远不如直接使用EC专属函数简洁。
修改后运行程序,输出的私钥PEM会和原始内容完全一致。
内容的提问来源于stack exchange,提问作者The Quantum Physicist
相关产品推荐
相关产品推荐

