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

RSA密钥对生成证书后TLS握手失败问题排查

代码存在的问题及修复方案

  • 目录判断逻辑异常:仅当cert目录不存在时才会执行证书生成逻辑,若目录已存在会直接跳过生成,使用旧的无效证书。建议在判断内新增Directory.CreateDirectory("cert")确保目录创建,或移除该判断强制生成新证书。
  • 增强密钥用法OID配置错误:当前使用的1.3.6.1.5.5.7.3.8是时间戳用途的OID,TLS服务端证书需要配置服务器身份验证对应的OID1.3.6.1.5.5.7.3.1,否则证书用途校验失败导致握手失败。
  • 服务器证书缺少独立密钥对:当前服务器证书复用了根CA的RSA密钥对,不符合证书规范,部分TLS协议栈会直接拒绝这类证书。
  • 服务器证书密钥用法缺失:当前仅配置了DigitalSignature、NonRepudiation标志,缺少TLS握手必需的KeyEncipherment标志,无法完成预主密钥加密校验。
  • PFX导出未携带私钥:生成的serverCert仅包含公钥证书,未绑定对应私钥,导出的PFX文件无法被服务端用于握手阶段的密钥解密。

修正后代码

private void GenerateCertificate()
{
    // 确保cert目录存在
    if (!Directory.Exists("cert"))
    {
        Directory.CreateDirectory("cert");
    }
    
    // 生成根CA独立密钥对
    using RSA rootRsa = RSA.Create(2048);
    CertificateRequest rootRequest = new CertificateRequest("CN=localhost", rootRsa, HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);
    rootRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
    rootRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(rootRequest.PublicKey, false));

    using X509Certificate2 rootCert = rootRequest.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-45), 
                    DateTimeOffset.UtcNow.AddDays(365));
    // 导出客户端信任的根证书
    File.WriteAllText("cert\\certificate.crt", new string(PemEncoding.Write("CERTIFICATE",
                    rootCert.Export(X509ContentType.Cert))));

    // 生成服务器独立密钥对
    using RSA serverRsa = RSA.Create(2048);
    CertificateRequest serverRequest = new CertificateRequest("CN=localhost", serverRsa, HashAlgorithmName.SHA256,
                    RSASignaturePadding.Pkcs1);
    serverRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
    // 补全密钥用法,新增KeyEncipherment
    serverRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | 
                    X509KeyUsageFlags.NonRepudiation | X509KeyUsageFlags.KeyEncipherment, false));
    // 修改为服务端身份验证OID
    serverRequest.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension( new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, 
                    true));
    serverRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(serverRequest.PublicKey, false));

    using X509Certificate2 signedServerCert = serverRequest.Create(rootCert, DateTimeOffset.UtcNow.AddDays(-1),
                    DateTimeOffset.UtcNow.AddDays(90), new byte[] { 1, 2, 3, 4 });
    // 给服务器证书绑定私钥
    using X509Certificate2 serverCertWithKey = signedServerCert.CopyWithPrivateKey(serverRsa);
    // 导出带私钥的PFX文件
    File.WriteAllBytes("cert\\server.pfx", serverCertWithKey.Export(X509ContentType.Pfx));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:54:03