.Net SslStream avec Certificat du Client
Je vais avoir aucune chance dans l'obtention de certificats client de travailler avec mon SslStream projet. Peu importe ce que je fais, je n'arrive pas à réellement utiliser le certificat du client, malgré le fait que tous les certificats sont valides et fiables, et j'ai importé le certificat d'autorité de certification pour ceux que j'ai produit moi-même, et il ne fonctionne tout simplement pas. Quelque chose doit m'échapper, mais j'ai été plus d'une douzaine de fois, examiné la documentation, des exemples et des heures de recherche sur google, et je ne peux pas le faire fonctionner. Ce que je fais mal?
Le Client:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace SslClient
{
class SslClientProgram
{
static void Main(string[] args)
{
TcpClient client = new TcpClient("localhost", 443);
SslStream stream = new SslStream(client.GetStream(), false, VerifyServerCertificate, null);
Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
string location = assembly.Location;
int pos = location.LastIndexOf('\\');
location = location.Substring(0, pos);
X509Certificate2 certificate = new X509Certificate2(location + "\\my.client.certificate.pfx", "password");
stream.AuthenticateAsClient("my.host.name", new X509Certificate2Collection(certificate), System.Security.Authentication.SslProtocols.Tls, false);
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
while (true)
{
string line = System.Console.ReadLine();
writer.WriteLine(line);
writer.Flush();
if (line == "close") break;
line = reader.ReadLine();
System.Console.WriteLine("Received: {0}", line);
}
stream.Close();
}
private static bool VerifyServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
}
}
Le Serveur:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace SslServer
{
class SslServerProgram
{
static void Main(string[] args)
{
TcpListener server = new TcpListener(System.Net.IPAddress.Loopback, 443);
server.Start();
TcpClient client = server.AcceptTcpClient();
SslStream stream = new SslStream(client.GetStream(), false, VerifyClientCertificate, null);
Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
string location = assembly.Location;
int pos = location.LastIndexOf('\\');
location = location.Substring(0, pos);
X509Certificate2 certificate = new X509Certificate2(location + "\\my.server.certificate.pfx", "password");
stream.AuthenticateAsServer(certificate, false, System.Security.Authentication.SslProtocols.Tls, false);
if (stream.RemoteCertificate != null)
{
System.Console.WriteLine(stream.RemoteCertificate.Subject);
}
else
{
System.Console.WriteLine("No client certificate.");
}
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
bool clientClose = false;
while (!System.Console.KeyAvailable)
{
System.Console.WriteLine("Waiting for data...");
string line = reader.ReadLine();
System.Console.WriteLine("Received: {0}", line);
if (line == "close")
{
clientClose = true;
break;
}
writer.WriteLine(line);
writer.Flush();
}
if (!clientClose) System.Console.ReadKey();
stream.Close();
server.Stop();
}
private static bool VerifyClientCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
}
}
Peu importe ce que j'essaie, le serveur dit toujours "Pas de certificat client."
Vous devez vous connecter pour publier un commentaire.
Comme il s'avère,
AuthenticateAsServer
est la clé ici - plus précisément, la deuxième paramètre.Si
clientCertificateRequired
estfalse
, il sera complètement ignorer les certificats clients, même si celle-ci est spécifiée par le client, mais si c'esttrue
, elle leur permettra d', mais ne permet pas de lever une exception si aucun certificat client n'est spécifié.Idiot de moi - je pensais
clientCertificateRequired
défini sur true, il serait réellement nécessaire, à cause de la .Net de la documentation décrit comme:Mon idée était que si c'était
true
, et je n'ai pas envoyer un certificat client, alors il serait un échec. C'est un cas clair de moins de complètement de la documentation précise sur la part de Microsoft.Mise à jour: Le documentation la plus récente pour la
clientCertificateRequired
paramètre comprend la phrase "Notez que ce n'est qu'une demande -- si aucun certificat n'est fourni, le serveur accepte la demande de connexion."