我试图编写一个客户端服务器库,以使我的局域网计算机相互通信。由于这很大程度上是一种自我教育的尝试,因此我试图使这些连接通过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.");
}
在此,
this.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");
}
我已经按照this post's instructions生成了客户端和服务器证书,并在客户端和服务器上都将根权限安装到了本地计算机的受信任权限中。然后,我为客户端和服务器生成了证书,将.cer文件的副本放在客户端/服务器可以访问的位置(加载以获取X509Certificate对象),并使用私钥在各自机器的个人存储中安装了。现在,当客户端和服务器位于同一台计算机上时,一切正常。但是,当我生成新证书并将其放在第二台计算机上时,客户端和服务器现在无法相互认证。连接已建立,加密和签名,但IsMutuallyAuthenticated为false。我怎样才能解决这个问题?我究竟做错了什么?
编辑:LocalCertificateSelectionCallback和另一个回调告诉我,客户端找到一个本地证书,这是我的,没有远程证书,也没有可接受的颁发者。我的证书已选择,并从本地证书选择中返回。客户端上没有SSL策略错误,在主机上,我仍然获得RemoteCertificateNotAvailable。用Wireshark嗅探此事务,我看到一个标准的TCP握手,然后是几百字节的乱码,其中包括主机证书的名称,然后是标记事务结束的FIN,ACK数据包。因此,即使由LocalCertificateSelectionCallback例程选择了客户端证书,也确实不会发送该客户端证书。是什么原因造成的?我该如何解决?
最佳答案
SSLStream的构造函数具有RemoteCertificateVAlidationCallback参数。应该会有所帮助。