OpenSSL 3.1.0中使用EVP_DigestSign_* API进行RSA签名的密钥问题
问题分析与解决方案
核心原因
你用EVP_RSA_gen(2048)生成的是RSA*类型的密钥对象,但EVP_DigestSignInit函数要求传入的密钥参数是EVP_PKEY*类型(这也是EC密钥能用的原因,EVP_EC_gen直接返回EVP_PKEY*)。类型不匹配导致无法正确获取密钥,触发error:40800066:lib(129)::cant get key.错误。
修复步骤
将RSA包装为EVP_PKEY
生成RSA密钥后,需要用EVP_PKEY_new()创建空的EVP_PKEY对象,再用EVP_PKEY_assign_RSA()将RSA密钥关联进去:RSA* rsa = EVP_RSA_gen(2048); if (rsa == NULL) { // 处理生成错误 } EVP_PKEY* rsaKeyPair = EVP_PKEY_new(); if (rsaKeyPair == NULL || !EVP_PKEY_assign_RSA(rsaKeyPair, rsa)) { // 处理包装错误:若EVP_PKEY_assign_RSA失败,需手动释放rsa RSA_free(rsa); EVP_PKEY_free(rsaKeyPair); }注意:
EVP_PKEY_assign_RSA会接管RSA对象的所有权,后续只需释放EVP_PKEY*,无需单独释放RSA*。替换已弃用的EVP_MD_CTX_create
OpenSSL 3.x中EVP_MD_CTX_create()已被弃用,直接启用代码中注释的EVP_MD_CTX_new():ctxRSA = EVP_MD_CTX_new();完善资源清理
签名完成后,务必释放所有申请的资源:EVP_MD_CTX_free(ctxRSA); EVP_PKEY_free(rsaKeyPair); OPENSSL_free(sig);
修复后的关键代码片段
// 生成并包装RSA密钥 RSA* rsa = EVP_RSA_gen(2048); if (rsa == NULL) { ERR_error_string(ERR_get_error(), err_buffer); // 错误处理 } EVP_PKEY* rsaKeyPair = EVP_PKEY_new(); if (rsaKeyPair == NULL || !EVP_PKEY_assign_RSA(rsaKeyPair, rsa)) { ERR_error_string(ERR_get_error(), err_buffer); RSA_free(rsa); EVP_PKEY_free(rsaKeyPair); // 错误处理 } // 签名流程 EVP_MD_CTX* ctxRSA = EVP_MD_CTX_new(); if (ctxRSA == NULL) { ERR_error_string(ERR_get_error(), err_buffer); // 错误处理 } int rc = EVP_DigestSignInit(ctxRSA, NULL, EVP_sha256(), NULL, rsaKeyPair); if (rc != 1) { ERR_error_string(ERR_get_error(), err_buffer); // 错误处理 } // 后续DigestSignUpdate、DigestSignFinal逻辑保持不变 // 资源清理 EVP_MD_CTX_free(ctxRSA); EVP_PKEY_free(rsaKeyPair); OPENSSL_free(sig);
额外说明
- OpenSSL 3.x推荐统一使用
EVP_PKEY接口处理所有密钥类型,避免直接操作RSA/EC等底层对象,提升代码兼容性。 - 若编写新代码,更推荐用
EVP_PKEY_generate结合参数模板生成RSA密钥,符合OpenSSL 3.x的设计风格:EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); if (pctx == NULL || EVP_PKEY_keygen_init(pctx) <= 0 || EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, 2048) <= 0) { // 错误处理 } EVP_PKEY* rsaKeyPair = NULL; if (EVP_PKEY_generate(pctx, &rsaKeyPair) <= 0) { // 错误处理 } EVP_PKEY_CTX_free(pctx);
内容的提问来源于stack exchange,提问作者Michał Pura
相关产品推荐
相关产品推荐

