获取“服务器模式 SSL 必须使用具有关联私钥的证书”使用 .cer 而不是 .pfx 在 X509Certificate2 中出错

如何解决获取“服务器模式 SSL 必须使用具有关联私钥的证书”使用 .cer 而不是 .pfx 在 X509Certificate2 中出错

我在自定义 Web 服务器中使用 .cer 和 .key 文件通过 SslStream.AuthenticateAsServerAsync() 验证 ssl。 X509Certificate2的创建过程是这样的:

var bytes = File.ReadAllBytes(certificatePath);
using var publicKey = new X509Certificate2(bytes,default(string));


var privateKeyText = File.ReadAllText(privateKeyPath);
var privateKeyBlocks = privateKeyText.Split("-",StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim('\n')).ToArray();
var privateKeyBytes = Convert.FromBase64String(privateKeyBlocks[1]);

        
using var rsa = RSA.Create();

if (privateKeyBlocks[0] == "BEGIN PRIVATE KEY")
   {
      rsa.ImportPkcs8PrivateKey(privateKeyBytes,out _);
   }
else if (privateKeyBlocks[0] == "BEGIN RSA PRIVATE KEY")
   {
      rsa.ImportRSAPrivateKey(privateKeyBytes,out _);
   }

var keyPair = publicKey.copyWithPrivateKey(rsa);
return new X509Certificate2(keyPair.Export(X509ContentType.Pfx));

在使用 .pfx 时一切正常,但是通过使用此代码将 .pfx 文件(并生成它的过程)替换为 .cer 和 .key 文件,在 SslStream.AuthenticateAsServerAsync() 中我得到了这个错误:>

System.Security.Authentication.AuthenticationException: The server mode SSL must use a certificate with the associated private key.

我使用的其他方式:

 X509Certificate2 certWithKey = default;
 try
 {
   string keyPem = File.ReadAllText(keyFile);
   byte[] keyDer = UnPem(keyPem);
   using (X509Certificate2 certOnly = new X509Certificate2(cerFile))
   {
       using (RSA rsa = RSA.Create())
       {
           // For "BEGIN PRIVATE KEY"
           rsa.ImportPkcs8PrivateKey(keyDer,out _);
           var tmp = certOnly.copyWithPrivateKey(rsa);
           certWithKey = new X509Certificate2(tmp.Export(X509ContentType.Pfx));
       }
   }
   Serilog.Log.ForContext("Path",cerFile).information("Create certificate from {FileName} successfully.",Path.GetFileName(cerFile));
 }
 catch (Exception ex)
 {
    Logger.LogError(ex,"Error in create certificate from {Path}",cerFile);
 }
 return certWithKey;
 static byte[] UnPem(string pem)
 {
    // This is a shortcut that assumes valid PEM
    // -----BEGIN words-----\nbase64\n-----END words-----
    const string Dashes = "-----";
    int index0 = pem.IndexOf(Dashes);
    int index1 = pem.IndexOf('\n',index0 + Dashes.Length);
    int index2 = pem.IndexOf(Dashes,index1 + 1);
    return Convert.FromBase64String(pem.Substring(index1,index2 - index1));
}

也在 .net 5 中使用这种新方法

return X509Certificate2.CreateFromPemFile(certificatePath,privateKeyPath);

但问题没有解决

我想要的只是从 .cer 和 .key 文件创建 X509Certificate2,而不是从 .pfx 文件。 我不知道这个问题在哪里。创建 X509Certificate2 导致问题,或者我错过了一些其他的东西(例如在验证 sslstream 中)。坦克帮助我了解问题和执行此操作的最佳方法

解决方法

通过 bartonjs 的坦克,我的问题解决了:

string pass = Guid.NewGuid().ToString();
var certificate = X509Certificate2.CreateFromPemFile(certificatePath,privateKeyPath);
return new X509Certificate2(certificate.Export(X509ContentType.Pfx,pass),pass);

使用随机密码从 .cer 文件创建内存中 .pfx 类型证书并使用它代替原始证书。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?