我正在阅读msdn info articels很长一段时间,但我仍然无法理解它。
基于不需要客户端身份验证的假设:
1.当我拨打SslStream.AuthenticateAsServer(...)
时,我是在服务器端还是在客户端调用此方法?
2.建立SslStream时,只有服务器负责建立SslStream
或服务器和客户端?
3.如果它只是服务器的责任,是否意味着客户端可以只使用常规send()
和recieve()
操作而无需自己创建SslStream ?
4.客户端是否需要获取证书文件才能验证服务器?
非常感谢您提前,我真的找不到有关此主题的更多信息,而且我已经搜索了很长时间的这些信息..
答案 0 :(得分:6)
编辑: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证书完成。在客户端,您必须使用服务器名称为证书的CNAME(公用名)来调用SslStream.AuthenticateAsClient(serverName)
(例如:“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);
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
然后代码中的其他地方:
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;
}