SslStream和身份验证

Wei*_*rce 5 c# ssl certificate sslstream ssl-certificate

我正在阅读msdn info articels很长一段时间,但我仍然无法理解它.

基于不需要客户端身份验证的假设:

1.当我打电话时SslStream.AuthenticateAsServer(...),我在服务器端或客户端调用此方法吗?

2.建立SslStream时,只有服务器负责建立SslStream服务器和客户端?

3.如果只是服务器的责任,是否意味着客户端可以只使用常规send()recieve()操作而无需自己创建SslStream?

4.客户端是否需要获取证书文件才能验证服务器?

非常感谢你提前,我真的找不到关于这个主题的很多信息,我一直在寻找这个信息很长一段时间..

Max*_*Max 7

编辑:MSDN在本页底部有一个完整的工作示例:https://msdn.microsoft.com/en-us/library/system.net.security.sslstream?f = 255&MSPPError = -2147217396 - 所以你应该真的开始在那里进行实验,因为这个例子就是全部.

原始答案:

我必须在这个答案前面说"大多数SSL实现都需要"不需要客户端身份验证".客户端身份验证很少见:您可能会在VPN应用程序,银行业和其他安全应用程序中看到它.因此,当您尝试使用SslStream()在没有客户端身份验证的情况下启动时,这将是明智的.

当您浏览到HTTPS网站时,您不会使用客户端证书对您的浏览器进行身份验证,而只是要确认您要连接的服务器名称与证书中找到的CNAME匹配,并且服务器证书是由你的机器信任的CA--它还有更多,但基本上就是归结为它的原因.

所以,说了这些,让我回答你的问题:

1)SslStream.AuthenticateAsServer(...)仅在服务器端使用服务器509证书完成.在客户端,您必须SslStream.AuthenticateAsClient(serverName)使用服务器名称作为证书的CNAME(通用名称)进行调用(例如:"domain.com")

2)SslStream必须为客户端和服务器创建.你只是通过"包裹"它来创建它TcpClient NetworkStream(例如,但还有其他方法)

服务器示例:

// assuming an 509 certificate has been loaded before in an init method of some sort
X509Certificate serverCertificate = X509Certificate2.CreateFromCertFile("c:\\mycert.cer"); // for illustration only, don't do it like this in production
...

// assuming a TcpClient tcpClient was accepted somewhere above this code
slStream sslStream = new SslStream(tcpClient.GetStream(), false);
sslStream.AuthenticateAsServer(
                serverCertificate,
                false, 
                SslProtocols.Tls, 
                true);
Run Code Online (Sandbox Code Playgroud)

3)否.通信在两端都是加密的.所以双方都必须使用SslStream.在客户端上使用receive()send()将产生二进制加密数据.

4)否.客户端将回调方法传递给SslStream创建,以验证服务器接收的证书.

例:

// assuming a TcpClient tcpClient was connected to the server somewhere above this code
SslStream sslStream = new SslStream(
            tcpClient.GetStream(),
            false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate),
            null
            ); 
sslStream.AuthenticateAsClient(serverName); // serverName: "domain.com" for example
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中的其他地方:

public static bool ValidateServerCertificate(
          object sender,
          X509Certificate certificate,
          X509Chain chain,
          SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None) {
            return true;
        }

        Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

        // refuse connection
        return false;
    }
Run Code Online (Sandbox Code Playgroud)