1

我正在尝试编写一个客户端-服务器库,让我的 LAN 计算机相互通信。由于这主要是一种自我教育尝试,因此我试图通过 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");
}

我已经按照这篇文章的说明生成了客户端和服务器证书,并将根权限安装到客户端和服务器上本地计算机的受信任的权限中。然后,我为客户端和服务器生成证书,将 .cer 文件的副本放在客户端/服务器可访问的位置(加载以获取 X509Certificate 对象),并在各自机器的个人存储中安装带有私钥的文件。现在,当客户端和服务器在同一台机器上时,一切正常。但是当我生成一个新证书并将其放在第二台机器上时,客户端和服务器现在无法相互验证。连接已建立、加密和签名,但 IsMutuallyAuthenticated 为假。我怎样才能解决这个问题?我究竟做错了什么?

编辑:LocalCertificateSelectionCallback 和另一个回调告诉我客户端找到一个本地证书,这是我的,没有远程证书,也没有可接受的颁发者。我的证书被选中并从本地证书选择中返回。客户端没有 SSL 策略错误,在主机端,我仍然得到 RemoteCertificateNotAvailable。用 Wireshark 嗅探这个事务,我看到一个标准的 TCP 握手,然后是几百字节的乱码,其中包括主机证书的名称,然后是 FIN、ACK 数据包,这些数据包标志着事务的结束。所以客户端证书确实没有被发送,即使它是由 LocalCertificateSelectionCallback 例程选择的。什么可能导致这种情况?我该如何解决?

4

1 回答 1

0

SSLStream 的构造函数具有 RemoteCertificateVALidationCallback 参数。它应该有帮助。

于 2012-12-02T09:49:18.160 回答