Bonjour

Je débute en SSL et après de longues heures de lecture j'ai pu faire un client et un serveur TCP qui communiquent en TLS.
Il me reste quelques questions sur SSL que j'ai posé sur le forum sécurité http://www.developpez.net/forums/d15...certification/ mais globalement j'ai compris les principes.

Pour mon appli je ne demande pas le certificat au client mais il reste la gestion du certificat du serveur.
Ça fonctionne en créant un certificat auto signé via la console MMC puis en faisant un export d'un fichier .pfx que j'ai cru comprendre être la clé privée, protégée par un mot de passe à l'export. Je place ce fichier pfx à coté du .exe et hop ca fonctionne avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
String fileName = "MonCertif.pfx" ;
X509Certificate2 certificate = new X509Certificate2(fileName,"password");
Plusieurs questions :
1) ce mot de passe qui est demandé à l'export du certificat protège quoi ? parce que pour le moment j'ai un mot de passe en clair qui est donc super pas sécur puisque le code est super facile à lire pour quiconque et a ma connaissance le seul moyen de le rendre sécur serait de demander le mot de passe à l'utilisateur et de le comparer à un hash...un peu pénible pour l'utilisateur, surtout si je sais pas lui dire à quoi il sert ! :-)
2) Y a t-il un moyen de pointer directement sur les certificats que l'on gère avec MMC ?
3) pour le déploiement de l'application chez des clients, comment doit on procéder pour l'installation du certificat que l'on va du coup devoir fournir au client avec l'appli ? (perso j'utilise innoSetup)

Merci par avance

pour info, voici le code complet du serveur (code largement inspiré par d'autres...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
using System;
using System.Configuration;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
 
 
namespace MutualSslDemo.Server
{
    class Program
    {
        static void Main(string[] args)
        {
            //  port
            UInt16 port = 0;
            string UserEntry = "";
            bool IsOk = false;
            do
            {
                Console.WriteLine("Saisir le numéro de port à surveiller : ");
                UserEntry = Console.ReadLine();
                IsOk = UInt16.TryParse(UserEntry, out port);
            } while (!IsOk );
 
            //  certificate and password
            var fileName = "MonCertif.pfx"; 
 
            X509Certificate2 certificate = new X509Certificate2(fileName,"password");
 
 
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);
            SslTcpServer.RunServer((int)port, certificate);
        }
 
        static bool OnRemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return (sslPolicyErrors == SslPolicyErrors.None);
        }
 
        public sealed class SslTcpServer
        {
            // The certificate parameter specifies the name of the file 
            // containing the machine certificate.
            public static void RunServer(int serverPort, X509Certificate2 certificate)
            {
                // Create a TCP/IP (IPv4) socket and listen for incoming connections.
                var listener = new TcpListener(IPAddress.Any, serverPort);
                listener.Start();
 
 
                while (true)
                {
                    Console.WriteLine("Waiting for a client to connect...");
                    // Application blocks while waiting for an incoming connection.
                    // Type CNTL-C to terminate the server.
                    var client = listener.AcceptTcpClient();
                    ProcessClient(client, certificate);
                }
            }
 
            static void ProcessClient(TcpClient client, X509Certificate certificate)
            {
                // A client has connected. Create the SslStream using the client's network stream.
                var sslStream = new SslStream(client.GetStream(), false);
 
                try
                {
                    // Authenticate the server and NOT requires the client to authenticate.
                    sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Default, true);
 
                    // Authenticate the server and requires the client to authenticate.
//sslStream.AuthenticateAsServer(certificate, true, SslProtocols.Default, true);
 
 
                    // Display the properties and settings for the authenticated stream.
                    DisplaySecurityLevel(sslStream);
                    DisplaySecurityServices(sslStream);
                    DisplayCertificateInformation(sslStream);
                    DisplayStreamProperties(sslStream);
 
                    // Set timeouts for the read and write to 5 seconds.
                    sslStream.ReadTimeout = 5000;
                    sslStream.WriteTimeout = 5000;
                    // Read a message from the client.   
                    Console.WriteLine("Waiting for client message...");
                    string messageData = ReadMessage(sslStream);
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Received: {0}", messageData);
                    Console.ResetColor();
 
                    // Write a message to the client.
                    byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>");
                    Console.WriteLine("Sending hello message.");
                    sslStream.Write(message);
                }
                catch (AuthenticationException e)
                {
                    Console.WriteLine("Exception: {0}", e.Message);
                    if (e.InnerException != null)
                    {
                        Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                    }
                    Console.WriteLine("Authentication failed - closing the connection.");
                    sslStream.Close();
                    client.Close();
                    return;
                }
                finally
                {
                    // The client stream will be closed with the sslStream
                    // because we specified this behavior when creating
                    // the sslStream.
                    sslStream.Close();
                    client.Close();
                }
            }
 
            static string ReadMessage(SslStream sslStream)
            {
                // Read the  message sent by the client.
                // The client signals the end of the message using the
                // "<EOF>" marker.
                byte[] buffer = new byte[2048];
                StringBuilder messageData = new StringBuilder();
                int bytes = -1;
                do
                {
                    // Read the client's test message.
                    bytes = sslStream.Read(buffer, 0, buffer.Length);
 
                    // Use Decoder class to convert from bytes to UTF8
                    // in case a character spans two buffers.
                    Decoder decoder = Encoding.UTF8.GetDecoder();
                    char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                    decoder.GetChars(buffer, 0, bytes, chars, 0);
                    messageData.Append(chars);
                    // Check for EOF or an empty message.
                    if (messageData.ToString().IndexOf("<EOF>") != -1)
                    {
                        break;
                    }
                } while (bytes != 0);
 
                return messageData.ToString();
            }
 
            static void DisplaySecurityLevel(SslStream stream)
            {
                Console.WriteLine("Cipher: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength);
                Console.WriteLine("Hash: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength);
                Console.WriteLine("Key exchange: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength);
                Console.WriteLine("Protocol: {0}", stream.SslProtocol);
            }
 
            static void DisplaySecurityServices(SslStream stream)
            {
                Console.WriteLine("Is authenticated: {0} as server? {1}", stream.IsAuthenticated, stream.IsServer);
                Console.WriteLine("IsSigned: {0}", stream.IsSigned);
                Console.WriteLine("Is Encrypted: {0}", stream.IsEncrypted);
            }
 
            static void DisplayStreamProperties(SslStream stream)
            {
                Console.WriteLine("Can read: {0}, write {1}", stream.CanRead, stream.CanWrite);
                Console.WriteLine("Can timeout: {0}", stream.CanTimeout);
            }
 
            static void DisplayCertificateInformation(SslStream stream)
            {
                Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus);
 
                X509Certificate localCertificate = stream.LocalCertificate;
                if (stream.LocalCertificate != null)
                {
                    Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.",
                        localCertificate.Subject,
                        localCertificate.GetEffectiveDateString(),
                        localCertificate.GetExpirationDateString());
                }
                else
                {
                    Console.WriteLine("Local certificate is null.");
                }
                // Display the properties of the client's certificate.
                X509Certificate remoteCertificate = stream.RemoteCertificate;
                if (remoteCertificate != null)
                {
                    Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.",
                        remoteCertificate.Subject,
                        remoteCertificate.GetEffectiveDateString(),
                        remoteCertificate.GetExpirationDateString());
                }
                else
                {
                    Console.WriteLine("Remote certificate is null.");
                }
            }
        }
    }
}