在TLS握手期间,服务器模式SSL必须使用具有关联私钥的证书

时间:2015-07-30 19:23:15

标签: c# ssl ssl-certificate x509certificate2

我有证书someCert.cer。我使用MMC实用程序将其导入我的本地证书库。我的C#应用​​程序可以使用以下代码访问它:

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
X509Certificate2 certificate = null;
store.Open(OpenFlags.ReadOnly);
try
{
    var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, "THUMBPRINT", false);
    certificate = certificateCollection[0];
}
finally
{
    store.Close();
}

应用程序公开TCP套接字,当我尝试使用我的客户端应用程序连接它时,我得到异常: The server mode SSL must use a certificate with the associated private key

确实我的证书的PrivateKey属性为空。我是否错误地导入了我的证书,或者在将证书导入商店之前是否应该对证书进行某些操作?

我的服务器身份验证代码如下:

stream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, true);

3 个答案:

答案 0 :(得分:1)

要进行正确的tls握手,服务器必须具有与证书中嵌入的公钥配对的私钥。当客户端连接时,它将显示证书。这允许验证服务器是否基于发布机构的信任所声称的服务器。在握手期间,客户端将生成对称密码密钥,该密钥使用证书中的公钥为服务器加密。服务器将使用私有密钥解密对称密钥。

我非常简单地在这里简化握手过程。所以带上一粒盐就可以了。 (没有加密双关语)

答案 1 :(得分:0)

在杰西(Jesse)的评论和戴夫(Dave)的回答之间,我可以得出结论,我以某种方式创建并安装了某种部分证书,对它进行了部分整理。

我已经使用makecert.exe制作了一个证书,并设法将其安装并加载到Kestrel中,但是当来自Chrome的请求传入时,它失败了。

我找不到pvk2pfx.exe的副本,无法从makecert.exe踢出的两个文件中制作一个PFX文件,所以我只是尝试不使用它而继续。

在失败之后,阅读上面的内容,我认为PFX步骤是强制性的。因此,我使用了经典的PowerShell 4(PS6 Core无法加载该模块):

> $cert = New-SelfSignedCertificate -certstorelocation cert:\currentuser\my -dnsname windows
> $pwd = ConvertTo-SecureString -String 'password1234' -Force -AsPlainText
> $path = 'cert:\currentuser\my\' + $cert.thumbprint
> Export-PfxCertificate -cert $path -FilePath c:\DATA\~Scrap\windows.pfx -Password $pwd

贷记https://medium.com/the-new-control-plane/generating-self-signed-certificates-on-windows-7812a600c2d8

TBH,我本来是半打工的。我在商店中生成证书的第一个命令后停了下来,但是在被Chrome击中时,却给了我一个不同于Kestrel堆栈的奇怪错误。同样,出于某些原因需要执行PFX步骤。

目前我无法找到一种方法来信任签名者,但是Chrome让我继续,以便在不那么累的时候进行排序。

答案 2 :(得分:0)

您是如何创建证书的? 创建证书时,还需要使用私钥对其进行签名。如果您已导出证书,则可能在某个时候可以选择提供密码。如果导出时未提供密码,则证书将不带私钥导出。