C#でSSL(サーバー証明書の検証なし版)

C#SSL通信を行う。

例として、インターネット上のWebサーバーとSSL通信を行う。

ここでは、問題を単純にするためサーバー証明書の検証は行わない。




手順は、以下のようになる。

1Webサーバー名からWebサーバーのIPアドレスDNSでルックアップ
2TcpClientを用いて、Webサーバーの443番ポートに接続する
3SslStreamを生成し、でSSL通信を開始
4SslStream#AuthenticateAsClientメソッドで、サーバー証明書の検証を行う(ここでは、検証せず無条件に許可する)
5HTTPリクエストを送信する
6HTTPレスポンスを受信する





例として、「google.com」とSSLで通信する

using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Text;

public class Program
{
    //サーバー証明書を検証するためのコールバックメソッド
    private static Boolean RemoteCertificateValidationCallback(Object sender, 
        X509Certificate certificate, 
        X509Chain chain, 
        SslPolicyErrors sslPolicyErrors)
    {
        //サーバー証明書を検証せずに無条件に許可する
        return true;
    }

    public static void Main()
    {
        //ホスト名とポート番号を指定
        String hostName = "google.com";
        Int32 port = 443;

        //
        using (TcpClient client = new TcpClient())
        {
            //接続先Webサーバー名からIPアドレスをルックアップ
            IPAddress[] ipAddresses = 
                Dns.GetHostAddresses(hostName);

            //Webサーバーに接続する
            client.Connect(new IPEndPoint(ipAddresses[0], port));
            
            //SSL通信の開始
            using (SslStream sslStream = 
                new SslStream(client.GetStream(), false, RemoteCertificateValidationCallback))
            {
                //サーバーの認証を行う
                //これにより、RemoteCertificateValidationCallbackメソッドが呼ばれる
                sslStream.AuthenticateAsClient(hostName);

                //HTTPリクエストをサーバーに送信する
                Byte[] req = 
                    Encoding.ASCII.GetBytes(String.Format("GET / HTTP/1.0\r\nHost: {0}\r\n\r\n", hostName));
                sslStream.Write(req);
                sslStream.Flush();

                //サーバーから受信したHTTPレスポンスを読み込んで
                //コンソールに表示数
                Byte[] res = new Byte[1024];
                Int32 n;
                while ( (n = sslStream.Read(res, 0, res.Length) ) > 0)
                {
                    String s = Encoding.ASCII.GetString(res, 0, n);
                    Console.WriteLine(s);
                }
            }
        }
    }
}



実行結果

実行すると、Webサーバーから以下のようなレスポンスが返される(コンソールに表示される)。

HTTP/1.0 301 Moved Permanently
Location: https://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Tue, 30 Apr 2013 07:51:05 GMT
Expires: Thu, 30 May 2013 07:51:05 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 220
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>