EDIT:MSDNは、Aがありますこのページの下部にある完全な作業例:https://msdn.microsoft.com/en-us/library/system.net.security.sslstream?f=255&MSPPError=-2147217396 - この例ではすべてのことがわかっているので、実際にそこで実験を開始する必要があります。
オリジナルの答え:私は、「クライアント認証が必要ではない」というこの回答を前書きしなければならない
は、SSLの実装のほとんどのケースです。クライアント認証はまれです.VPNアプリケーション、銀行業界などのセキュアなアプリケーションでは、認証が見られる可能性が高いです。だから、クライアント認証なしで起動するためにSslStream()を試してみるのは賢明でしょう。
HTTPS Webサイトを参照すると、クライアント証明書を使用してブラウザを認証するのではなく、接続するサーバー名を証明書にあるCNAMEと一致させ、サーバー証明書は、あなたのマシンが信頼するCAによって署名されています。それ以上のものはありますが、本質的にそれが何であるかです。
1)SslStream.AuthenticateAsServer(...)
がサーバー509証明書を使用してサーバー側でのみ行われます。
だから、私はあなたの質問に答えてみましょうと言いました。 SslStream
は、クライアントとサーバーの両方のために作成する必要があります):(「domain.com」の例)
2クライアント側では、サーバー名は、証明書のCNAME(一般名)であることをSslStream.AuthenticateAsClient(serverName)
を呼び出す必要があります。サーバ用
例は、単に「ラッピング」その周り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
を使用する必要があります。クライアント上でとsend()
を使用すると、バイナリで暗号化されたデータが得られます。
4)No.クライアントは、サーバーが受け取った証明書を検証するために、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;
}
iが文字列としてserverNameの中で、サーバーのIPアドレスを送信することができますか? – WeinForce
はい、できます(prodではお勧めできません)が、その場合はクライアント側でSSLエラーなどが発生し、ValidateServerCertificate()関数では常にtrueを返します。あなたの目的に合ったものを作ってください。 – John
serverNameがIPAddressに変換されているので、なぜ 'sslStream.AuthenticateAsClient(serverIpAsString)'を使用するとエラーになるのですか? また、 'ValidateServerCertificate'の値はどこに戻っていますか? – WeinForce