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

C/C++中如何使用OpenSSL生成符合X.509规范的DER编码公钥

错误根源

你当前的实现误导出了完整X509证书的DER编码,而Minecraft协议要求的是SubjectPublicKeyInfo(SPKI)结构的公钥DER编码,两者结构不匹配导致客户端解析公钥失败。
你使用的i2d_X509接口会导出包含证书版本、颁发者、有效期等额外字段的完整证书数据,这些内容是协议不需要的,客户端仅会按SPKI结构解析公钥,因此抛出重构失败错误。

正确实现方案

你不需要创建X509对象,直接使用OpenSSL提供的i2d_PUBKEY接口即可从EVP_PKEY结构导出符合要求的SPKI格式DER公钥,修改后的代码逻辑如下:

RSA* rsa = RSA_new();
if (!rsa)
    return false;

BIGNUM* exponent = BN_new();
if (!exponent)
{
    RSA_free(rsa);
    return false;
}

EVP_PKEY* pkey = EVP_PKEY_new();
if (!pkey)
{
    RSA_free(rsa);
    BN_free(exponent);
    return false;
}

BN_set_word(exponent, 65537);
RSA_generate_key_ex(rsa, 1024, exponent, NULL);

EVP_PKEY_set1_RSA(pkey, rsa);

// 正确导出SPKI格式DER公钥
std::vector<uint8_t> derPublicKey;
{
    // 先查询所需缓冲区大小
    int keyLength = i2d_PUBKEY(pkey, NULL);
    if (keyLength <= 0)
    {
        RSA_free(rsa);
        BN_free(exponent);
        EVP_PKEY_free(pkey);
        return false;
    }
    derPublicKey.resize(keyLength);
    uint8_t* keyPtr = derPublicKey.data();
    // 写入DER编码数据
    i2d_PUBKEY(pkey, &keyPtr);
}

// 释放资源逻辑和原有一致
RSA_free(rsa);
BN_free(exponent);
EVP_PKEY_free(pkey);
验证说明

1024位RSA公钥的SPKI结构DER编码长度通常在140字节左右,你可以输出导出后的derPublicKey长度做初步校验,若长度大于200字节则说明导出逻辑仍有问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:27:00