You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EC私钥创建异常:PEM格式文件生成错误原因排查求助

问题:OpenSSL生成EC密钥转PEM格式出错,私钥有效性存疑

我用以下代码创建EC_KEY,但转换为PEM格式文件时得到异常结果,不确定私钥是否正确,想找出问题所在:

#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/pem.h>

int main(){
    EC_KEY *ec_key = EC_KEY_new();
    EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1);

    if (EC_KEY_set_group(ec_key, group) != 1) {
        printf("SyncServer : Failed to set EC group\n");
        return 0;
    }

    if (EC_KEY_generate_key(ec_key) != 1) {
        printf("SyncServer : Failed to generate EC key\n");
        return 0;
    }

    EVP_PKEY *evp_key = EVP_PKEY_new();
    if (EVP_PKEY_set1_EC_KEY(evp_key, ec_key) != 1) {
        printf("failed to get ec_key!\n");
        return 0;
    }

    FILE *file = fopen("ec_private_key.pem", "w");
    if (file != NULL) {
        if (PEM_write_PrivateKey(file, evp_key, NULL, NULL, 0, NULL, NULL) != 1) {
            printf("Failed to create file\n");
            return 0;
        }
        fclose(file);
        }

     // Cleanup
    EVP_PKEY_free(evp_key);
    return 0;
}

生成的PEM结果:

-----BEGIN PRIVATE KEY-----
MIICDAIBADCCAWQGByqGSM49AgEwggFXAgEBMDwGByqGSM49AQECMQD/////////
/////////////////////////////////v////8AAAAAAAAAAP////8wewQw////
//////////////////////////////////////7/////AAAAAAAAAAD////8BDCz
MS+n4j7n5JiOBWvj+C0ZGB2cbv6BQRIDFAiPUBOHWsZWOY2KLtGdKoXI7dPsKu8D
FQCjNZJqoxmieh0AiWpnc6SCes2scwRhBKqHyiK+iwU3jrHHHvMgrXRuHTtii6eb
mFn3QeCCVCo4VQLyXb9VKWw6VF44cnYKtzYX3kqWJixvXZ6Yv5KS3Cn49B29KJoU
fOnaMRO18LjACmCxzh1+gZ16Qx18kOoOXwIxAP//////////////////////////
/////8djTYH0Ny3fWBoNskiwp3rs7BlqzMUpcwIBAQSBnjCBmwIBAQQw8q0GAqh4
BeAZSu7AzUanABFjIvyVlsJN56M21Ora7O4YbPn7Qb64bTJQjwQSNeiRoWQDYgAE
qdajmPcqDLjcO5MdpwQQ8IbgCa4LthXJC/ERemGVT8+VJ/ZOFjJe9JvH2al/Sz3R
zkiQ38dG7a8cseEEvLDtHhQFnzROBfeZzybLvcZHzEmI5kTZ6mlLQz7NQl7fZM+2
-----END PRIVATE KEY-----

问题分析与修复方案

1. 资源泄漏问题

代码存在两处未正确释放的资源,虽不直接导致PEM异常,但会引发内存泄漏:

  • EC_GROUP *group 创建后,仅关联到EC_KEY但未调用EC_GROUP_free(group)释放
  • EC_KEY *ec_key 关联到EVP_PKEY后,未调用EC_KEY_free(ec_key)释放

2. PEM格式与输出完整性问题

  • 你使用的PEM_write_PrivateKey输出的是PKCS#8通用私钥格式(开头为-----BEGIN PRIVATE KEY-----),这是标准格式,但如果需要EC密钥专用格式(开头为-----BEGIN EC PRIVATE KEY-----),应改用PEM_write_ECPrivateKey函数,兼容性更好。
  • 你提供的PEM结果末尾明显截断,大概率是文件写入时未正常完成,可通过添加错误日志或验证文件完整性排查。

3. 私钥有效性验证方法

用OpenSSL命令行直接验证生成的私钥:

# 验证PKCS#8格式私钥
openssl pkcs8 -in ec_private_key.pem -nocrypt -text
# 若改用EC专用格式,用以下命令
openssl ec -in ec_private_key.pem -text -noout

如果命令能正常输出曲线参数、私钥值和公钥值,说明私钥本身有效。

修复后的完整代码

#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <stdio.h>

int main(){
    EC_KEY *ec_key = EC_KEY_new();
    if (!ec_key) {
        printf("SyncServer : Failed to create EC_KEY\n");
        return 1;
    }

    EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp384r1);
    if (!group) {
        printf("SyncServer : Failed to create EC_GROUP\n");
        EC_KEY_free(ec_key);
        return 1;
    }

    if (EC_KEY_set_group(ec_key, group) != 1) {
        printf("SyncServer : Failed to set EC group\n");
        EC_GROUP_free(group);
        EC_KEY_free(ec_key);
        return 1;
    }
    // 关联后释放group,EC_KEY内部会持有引用
    EC_GROUP_free(group);

    if (EC_KEY_generate_key(ec_key) != 1) {
        printf("SyncServer : Failed to generate EC key\n");
        EC_KEY_free(ec_key);
        return 1;
    }

    // 方案1:写入EC专用私钥格式
    FILE *ec_file = fopen("ec_private_key_ec.pem", "w");
    if (ec_file) {
        if (PEM_write_ECPrivateKey(ec_file, ec_key, NULL, NULL, 0, NULL, NULL) != 1) {
            printf("Failed to write EC private key\n");
        }
        fclose(ec_file);
    }

    // 方案2:通过EVP_PKEY写入PKCS#8格式(原方案)
    EVP_PKEY *evp_key = EVP_PKEY_new();
    if (evp_key) {
        if (EVP_PKEY_set1_EC_KEY(evp_key, ec_key) == 1) {
            FILE *p8_file = fopen("ec_private_key_pkcs8.pem", "w");
            if (p8_file) {
                if (PEM_write_PrivateKey(p8_file, evp_key, NULL, NULL, 0, NULL, NULL) != 1) {
                    printf("Failed to write PKCS#8 private key\n");
                }
                fclose(p8_file);
            }
        } else {
            printf("failed to associate EC_KEY with EVP_PKEY!\n");
        }
        EVP_PKEY_free(evp_key);
    } else {
        printf("Failed to create EVP_PKEY\n");
    }

    // 释放EC_KEY
    EC_KEY_free(ec_key);
    return 0;
}

内容的提问来源于stack exchange,提问作者Ajith Nair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 23:27:24