29722


お世話になっております。  
C#でTCP、SSL通信を目的とし、以下のプログラムでサーバ側とクライアント側を作成しております。  
環境開発はWindows7 32bit、Visual Studio Community2015、NETFramework4.5.2です。  
PC2台にサーバとクライアントをそれぞれ立ち上げて行います。

クライアント側からサーバ側へ簡単なデータを送ります。  
このプログラムでデータの送受信を見ましたら、暗号化されていないデータが見られました。（以下のプログラムですとHelloがもろ見えでした）  
データを見たのはワイヤーシャークというソフトです。

サーバー側とクライアント側の初期のデータのやり取りを見ますと、  
Client→Server「client hello」  
↓  
Server→Client「server hello,certificate,server hello done」  
↓  
Client→Server「ClientKeyExchange,ChangeCipherSpec」

となっておりました。ですので、サーバ認証はOKだと思っております。(自己署名証明書です）  
その後、暗号化されたデータのやり取りを、、、と思ったのですが、暗号化されていませんでした。  
本当に申し訳ありませんが、送受信の部分はうろ覚えです。  
ただ、NetworkStreamのReadとwriteを使用して送受信をしていたのは覚えています。

質問は以下の通りです  
1.NetworkStreamでの通信は暗号化されないのでしょうか。もしそうでしたら、暗号化されたデータのやり取りをする方法をご教授いただきたいです。  
もしくは、ワイヤーシャークで取得しているデータは複合化されているデータなのでしょうか？  
2.記載したプログラムでSSLの初期の「clientHello」であったり、鍵の交換であったりのやり取りは、クライアントを認証する部分で勝手にやってくれるのでしょうか。  
それとも、本当は一つ一つのやり取り（鍵を生成して相手に渡す等）をプログラムする必要があるのでしょうか。

長くて申し訳ありません。よろしくお願いいたします。

サーバ側のプログラムになります。

[code]

    TcpListener listener = new TcpListener(IPAddress.Any, 1300);
    listener.Start();
    
    // クライアントとの接続を待ちます
    TcpClient clientSocket = listener.AcceptTcpClient();
    X509Certificate certificate = new X509Certificate("自己署名証明書のパス", 
    　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　"自己署名証明書のパスワード");
    
    // sslStreamを生成しclientSocketのデータを受け取ります
    using (SslStream sslStream = new SslStream(clientSocket.GetStream()))
    {
        // 証明書からクライアントを認証
        sslStream.AuthenticateAsServer(certificate);
    
        // 受信 
        Byte[] bytes = new Byte[17]; 
        NetworkStream RStream = clientSocket.GetStream();
        while((i = RStream.Read(bytes, 0, bytes.Length))!=0)  
        { 
             String data = System.Text.Encoding.UTF8.GetString(bytes, 0, i); 
             Console.WriteLine(String.Format("受信: {0}", data[0])); 
        } 
    }
    
[/code]

クライアント側のプログラムになります。

[code]

          static void Main(string[] args)
        {
        // Connect as client to port 1300
        string server = "127.0.0.1";
        TcpClient client = new TcpClient(server, 1300);
    
        // sslStreamを生成
        using (SslStream sslStream = new SslStream(client.GetStream(), false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
        {
            // サーバからの証明書を見て認証
            sslStream.AuthenticateAsClient(server);
    
            // 送るデータ
            Byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello");
            NetworkStream sstream = client.GetStream(); 
            stream.Write(data, 0, data.Length);
        }
        // クライアントとのコネクトを解除
        client.Close();
    }
    
    // 呼び出される↓
    public static bool ValidateServerCertificate(object sender, X509Certificate certificate,
        X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        // 証明書受け入れ
        return true;
    }
    
[/code]


CC BY-SA 3.0
2016-10-19T16:26:57.683
29717
2016-10-20T00:54:51.833
19213
question
c# ssl tcp
C#でTCP、SSL通信を行いたいです。暗号化されていない。


コメントで指摘されていますが、`sslStream`へ書き込み / 読み込みを行わなければSSL通信されません。コードにすると次のようになります。

サーバー部分

[code]

    var listener = TcpListener.Create(1300);
    listener.Start();
    using (var client = listener.AcceptTcpClient())
    using (var sslStream = new SslStream(client.GetStream())) {
        using (var certificate = new X509Certificate("自己署名証明書のパス", "自己署名証明書のパスワード"))
            sslStream.AuthenticateAsServer(certificate);
    
        var bytes = new Byte[5];
        var offset = 0;
        while (offset < bytes.Length) {
            var read = sslStream.Read(bytes, offset, bytes.Length - offset);
            if (read == 0)
                break;
            offset += read;
        }
        var data = Encoding.UTF8.GetString(bytes, 0, offset);
        Console.WriteLine("受信: {0}", data);
    }
    listener.Stop();
    
[/code]

クライアント部分

[code]

    var server = "127.0.0.1";
    using (var client = new TcpClient(server, 1300))
    using (var sslStream = new SslStream(client.GetStream(), false, delegate { return true; })) {
        sslStream.AuthenticateAsClient(server);
    
        var bytes = Encoding.UTF8.GetBytes("Hello");
        sslStream.Write(bytes);
    }
    
[/code]

質問文のコードからは問題がいくつか読み取れます。いきなり結果を求めるよりも、C#言語に慣れ、通常の`Stream`操作や`TcpClient`に慣れてからSSL通信に着手した方がよいように思えました。


CC BY-SA 3.0
2016-10-20T00:54:51.833
29722
2016-10-20T00:54:51.833
4236
29717
answer