Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SSLStream相互认证_C#_Security_Authentication_Ssl_Certificate - Fatal编程技术网

C# SSLStream相互认证

C# SSLStream相互认证,c#,security,authentication,ssl,certificate,C#,Security,Authentication,Ssl,Certificate,我正在尝试编写一个客户机-服务器库,以便让我的局域网计算机相互通信。由于这在很大程度上是一种自我教育的尝试,所以我尝试通过SSL实现这些连接。我的计划是维护一台主机,并让每个客户端维护一个到主机的相互验证的System.Net.SslStream实例。主机代码大致上类似于为简洁起见省略的错误处理: SslStream newStream = null; newStream = new SslStream(this.client.GetStream(), false); newStream.Aut

我正在尝试编写一个客户机-服务器库,以便让我的局域网计算机相互通信。由于这在很大程度上是一种自我教育的尝试,所以我尝试通过SSL实现这些连接。我的计划是维护一台主机,并让每个客户端维护一个到主机的相互验证的System.Net.SslStream实例。主机代码大致上类似于为简洁起见省略的错误处理:

SslStream newStream = null;
newStream = new SslStream(this.client.GetStream(), false);
newStream.AuthenticateAsServer(
    this.Certificate as X509Certificate,
    true,
    System.Security.Authentication.SslProtocols.Tls,
    false);

if (!(
    newStream.IsMutuallyAuthenticated &&
    newStream.IsEncrypted &&
    newStream.IsSigned))
{
    throw new AuthenticationException("Authentication results unsatisfactory.");
}
在本例中,此.Certificate是一个X509Certificate2。客户端代码如下所示:

SslStream connectionStream = new SslStream(this.client.GetStream(), false);

connectionStream.AuthenticateAsClient(
    this.ServerHostname,
    new X509CertificateCollection(new X509Certificate[] { (X509Certificate)this.Certificate }),
    SslProtocols.Tls,
    false);

if (!(
    connectionStream.IsEncrypted &&
    connectionStream.IsMutuallyAuthenticated &&
    connectionStream.IsSigned))
{
    throw new AuthenticationException("Authentication results unsatisfactory");
}
我通过以下方式生成了客户端和服务器证书,并将根权限安装到客户端和服务器上本地计算机的受信任权限中。然后,我为客户机和服务器生成了证书,将.cer文件的副本放在客户机/服务器可以访问的位置,加载以获取X509Certificate对象,并在各自机器的个人存储中安装了带有私钥的。现在,当客户机和服务器在同一台机器上时,一切都正常工作。但是,当我生成一个新证书并将其放在第二台计算机上时,客户端和服务器现在无法相互验证。连接已设置、加密和签名,但IsMutuallyAuthenticated为false。我怎样才能解决这个问题?我做错了什么


编辑:LocalCertificateSelectionCallback和另一个回调告诉我,客户端找到一个本地证书,它是我的,没有远程证书,也没有可接受的颁发者。已从本地证书选择中选择并返回我的证书。在客户端没有SSL策略错误,在主机端,我仍然可以获得RemoteCertificateNotAvailable。通过Wireshark嗅探这个事务,我看到一个标准的TCP握手,然后是几百字节的胡言乱语,其中包括主机证书的名称,然后是标记事务结束的FIN、ACK数据包。因此,即使LocalCertificateSelectionCallback例程选择了客户端证书,但它确实没有被发送。这可能是什么原因造成的?如何修复它?

SSLStream的构造函数具有RemoteCertificateVAlidationCallback参数。这应该会有帮助。

我刚刚完成了这个:在客户端,远程证书验证没有问题。在服务器端,它抱怨远程证书不可用。我可以在客户端本地计算机的个人密钥存储中清楚地看到带有私钥的证书。您可以尝试在客户端使用LocalCertificateSelectionCallback来检查是否确实选择了证书,Senit发现一个本地证书,它是我的,没有远程证书,也没有可接受的颁发者。已选择并返回我的证书。在主机端,我仍然可以获得RemoteCertificateNotAvailable。