c# - SSLStream 相互认证

标签 c# security authentication ssl certificate

我正在尝试编写一个客户端-服务器库,让我的 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");
}

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

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

最佳答案

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

关于c# - SSLStream 相互认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13667018/

相关文章:

c# - Windows Phone 8(工具包)图钉跳跃/闪烁

security - 是否有必要通过 HTTPS 加密浏览器数据?

security - 足以满足当今网络应用程序要求的位加密是多少

c# - 克隆一个我无法添加 ICloneable 的对象

c# - 字符串文字和字 rune 字可以连接吗?

C# - 每次向下循环 float

C#请求中的web服务密码需要加密

authentication - 无法登录admob帐户

linux - Git 权限被拒绝(公钥、gssapi-keyex、gssapi-with-mic)?

c# - 使用 C# 的原始 FTP SSL