C# SSL secure sockets

2019-04-12 08:11发布

问题:

I have a fine, working communicator application, written in C#. Now I need to implement a secure connection to the server. I've tried changing Socket and TcpClient objects into SslStream, but I got a few errors.

Firstly I generated a .cer certificate using makecert. OpenSSL certificates didn't worked for me, because they didn't include private key. Next I created a certificate object on the server and bound it to the SslStream:

X509Certificate serverCertificate = X509Certificate.CreateFromCertFile("ca.cer");
TcpClient clientSocket = this.tcpListener.AcceptTcpClient();
SslStream ssls = new SslStream(clientSocket.GetStream(), false);
ssls.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);

On the client side I'm doing this:

TcpClient client = new TcpClient(settings.IP, settings.Port);                                
sslStream = new SslStream(client.GetStream(), false,
    new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient(settings.IP);

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;

    Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
    return false;
}

but the AuthenticateAsClient function throws an exception. I tried several other method parameters, but none of this worked for me.

Could anyone help me, or explain step by step how to change simple sockets into secure ones? To be clear, SSL isn't the requirement - if there is simpler way to make the connection secure I can use that.


Edit: Message in exception is following:

The remote certificate is invalid according to the validation procedure.

回答1:

What's the exception ?

I guess you are getting the exception because your client certificate is rejected as valid from the server (unless you did the necessary things to set up trust).

When you use self signed certificates(the ones created by makecert), you would have to also supply a Client Certificate Validation callback when creating the SslStream object. Use this constructor overload http://msdn.microsoft.com/en-us/library/ms145056.aspx



回答2:

.CER file usually contains a certificate without a private key. Loading it into the server just won't work. You need a private key as well. The easiest is to generate the certificate and a key and save them together to PFX format. Then load the certificate and a key from PFX on the server.

Now with your code only only authenticate the server. Is this what you want to do (i.e. don't you want to authenticate the client on the server as well)?