First of all, I want to apologies for not writing. From one hand, this is not a good think for me to disappeared from development community horizons, from other hand, I am investing all my time into our better feature, which is good thing. There are too much things were done during last two years. And the good news are that we already delivered whatever was promised to deliver and know for sure that we are able to deliver even more in the future. But let’s come into business. First of all I have huge pipeline of interesting articles to share with you, second, some people from my team are also decided to contribute to the community and write Better Place development team blog. There are not too much there, but this is only a matter of time.
Today we’ll speak about security. About how to import OpenSSL private key into .NET application and use it aside with X509 public certificate to establish TLS connection with asymmetric encryption and two phase certificates handshake.
Let’s start from the very beginning. What is SSL? SSL is the secure way to communicate when transferred data is encrypted by using one time and per-session cipher. There are different implementations of such connection. The most famous one is the one all of you using when connection to https://someting… When doing this, your browser asks remote side to provide it public certificate for you in order to check it with local “authority” you trusted in. If everything is ok and the host defined on the remote certificate is the host you are speaking with, your browser allows communication after both sides decide about the one-time cipher for encryption.
You can implement this mode of SSL very easy by using SslStream class in .NET as 1-2-3.
1) Resolve host and open TcpClient connection to it
var host = new IPHostEntry();
try {
host = Dns.GetHostEntry(RemoteAddress.DnsSafeHost);
} catch (SocketException soe) {
if (soe.SocketErrorCode == SocketError.HostNotFound) {
host.HostName = RemoteAddress.DnsSafeHost;
}
}
Client.Connect(host.HostName, RemoteAddress.Port);
2) Initialize SSL encrypted stream to it by providing validation callback for remote certificate
var stream = new SslStream(Client.GetStream(), true, _validateCertificate);
3) Ask for authorization
stream.AuthenticateAsClient(host.HostName);
Inside remote certificate validation callback, you should decide what to do if something bad happened during negotiation phase.
private readonly RemoteCertificateValidationCallback _validateCertificate = (sender, certificate, chain, sslPolicyErrors) => {
var result = sslPolicyErrors == SslPolicyErrors.None;
if (!result) {
var err = new StringBuilder();
err.AppendFormat("Unable to establish security connection due to {0}. Error chain:", sslPolicyErrors);
foreach (var el in chain.ChainElements) {
foreach (var s in el.ChainElementStatus) {
err.AppendFormat("{0} – {1}", el.Certificate.Subject, s.StatusInformation);
}
}
Log.Warn(err.ToString());
}
return result;
};
So far, so good. Now, if everything is OK, just use SslStream as regular stream to write and read from the socket. All other complicated things will be done by .NET.
0 comments:
Post a Comment