OpenSSL 3.0如何从DER格式存储的EC公钥创建EVP_PKEY
问题原因
你的报错是OSSL_DECODER_CTX_new_for_pkey的参数配置和公钥编码输出的格式不匹配导致的,不需要换其他函数,修正参数配置即可。
你编码阶段用EVP_PKEY_PUBLIC_KEY参数输出的是标准SubjectPublicKeyInfo结构的DER格式公钥,解码阶段需要明确指定对应的结构和类型参数。
修复步骤
- 先确认你代码里的
FORMAT宏定义的值是"DER",和编码阶段的输出格式保持一致 - 修正解码函数的入参配置,你现有代码里的无效变量、错误参数都要调整:
structure参数不要传nullptr,填"SubjectPublicKeyInfo"匹配公钥的结构TYPE参数明确指定为"EC",匹配你生成密钥用的椭圆曲线类型- 确保传入的数据源是对端的公钥DER缓冲区、长度为对应的公钥长度,删掉无用的私钥相关变量
修复后的参考代码
EVP_PKEY* their_key = nullptr; // 这里FORMAT要和编码阶段一致,填"DER" // structure填"SubjectPublicKeyInfo",密钥类型填"EC" OSSL_DECODER_CTX* dec_ctx = OSSL_DECODER_CTX_new_for_pkey( &their_key, "DER", "SubjectPublicKeyInfo", "EC", EVP_PKEY_PUBLIC_KEY, nullptr, nullptr ); if (!dec_ctx) { // 错误处理 return nullptr; } // theirs是对端公钥DER缓冲区,theirsLen是公钥长度 int ret = OSSL_DECODER_from_data(dec_ctx, &theirs, &theirsLen); OSSL_DECODER_CTX_free(dec_ctx); if (ret <= 0) { // 解码失败,打印错误 unsigned long err = ERR_get_error(); char err_buf[512] = {0}; ERR_error_string_n(err, err_buf, sizeof(err_buf)); return nullptr; } // 解码成功,their_key就是可用的对端公钥EVP_PKEY实例
额外注意点
- 如果你后续需要直接传输EC公钥的裸未压缩坐标(65字节0x04开头的格式),可以用
d2i_PUBKEY或者先构造EC_KEY实例再赋值给EVP_PKEY的方案,当前你用的编解码流程是OpenSSL 3.0+推荐的标准方案,参数修正后可以正常使用。 - 所有生成的CTX、EVP_PKEY实例使用完成后要及时调用对应的free函数释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者broken-bytes
相关产品推荐
相关产品推荐

