RSA, Sslstream - Key Exchange

Asked

Viewed 133 times

3

Good people, I am using Sslstream to communicate between a client and server, using OPENSSL.

And this client of mine, is a machine (Digi), which as a requirement has to use RSA encryption.

Then I have to make a public key exchange between client and server.
I was testing for this switch in a way that I didn’t think was right, but I was doing it that way because I made a specific client to do this localhost or on any other machine that wasn’t the machine I’m actually going to use (my Digi).

I was doing it that way, both ends send the public key that way:

byte[] modulus = pubkey.Modulus;
sslStream.Write(modulus, 0, modulus.Length);
sslStream.Flush();

And both ends receive that way:

 byte[] exponent = {1, 0, 1};
 byte[] modulus = new byte[256];
 sslStream.Read(modulus, 0, modulus.Length);

 clientPublicKey.D = null;
 clientPublicKey.DP = null;
 clientPublicKey.DQ = null;
 clientPublicKey.Exponent = exponent;
 clientPublicKey.InverseQ = null;
 clientPublicKey.Modulus = modulus;
 clientPublicKey.P = null;
 clientPublicKey.Q = null;

But when testing on the machine (Digi) this same solution, I came to the conclusion that this key exchange is not done in the same way.

Is there any other way to do this key exchange? Because in the RSA object itself and SSLSTREAM has a property KeyExchangeAlgorithm.

1 answer

2

I will answer in a very general way, because I have no familiarity with SslStream (or even C# in general), but I think there are some misunderstandings in this question that I can help clarify.

The idea behind using a secure communications channel is that all content exchanged for that channel is protected (confidential, authenticated, honest). If that were not true, then there would be no point in using a SSL Stream - simply using a Stream...

Thus, the necessary steps to ensure the safety of a channel ("handshake", or Handshake) sane outsiders to use this channel. It makes no sense for you to use your own SslStream to send things like the encryption key, because the moment this stream is "usable" it is assumed that the hanshake (and therefore the key exchange) has already been done successfully.

Your conclusion that the exchange of keys is not done in this way is therefore correct. As well as your observation that there are properties [and methods] related to Handshake in the library’s own classes. The correct way to use a SslStream is to use its own methods to exchange keys (and protocol Handshake) and only start transmitting data through it when that process is successfully completed.

Opening a parenthesis: second the documentation, the class itself ensures that it remains illegible as long as the Handshake is not successfully completed:

Sslstream Property::Canread

Gets a Boolean value that indicates if the underlying stream is readable.

true whether the authentication occurred and the underlying stream is readable; if not false.

As for the right way to do this Handshake, I’ll leave it to those who understand C# better to answer. A glance at the documentation suggests the method AuthenticateAsServer, and its variants. Which leads me to the last misconception:

Then I have to make a public key exchange between client and server.

It’s not an exchange of keys that you need to do, but rather an exchange of certificates. The key alone guarantees only the confidentiality of a communication, but not its authenticity. If the client receives a key from the server and uses it to communicate confidentially, it will be sure that none Eavesdropper (spy, listen) will be intercepting the communication and reading its content. But he has no way to be sure of with whom he is communicating.

A fake server (e.g., in a attack "Man-in-the-Middle") could send the key his to the client - instead of the real server key - in order to make the client communicate with the client thinking it is communicating with the real server. Similarly, it can send its key to the real server, impersonating the client. Ultimately, instead of the communication being:

client real <----> server real

she will be:

client real <----> server falso, também client falso <----> server real

Which destroys all the security guarantees that the SSL protocol in principle would give you. The solution (one of the solutions, but the only one that is commonly used in practice) is to create a "security certificate", which is nothing more than a public key associated with a identity and both signed by a trusted entity (Trusted third-party) - jointly agreed.

A full description of what a certificate is and how to use it correctly (sometimes only the server uses it, sometimes the client as well) would be too extensive for that response, so I suggest you get better informed about how it works. It may even be through a separate question in Sopt itself (we had similar questions in the past), through which I would be willing to delve further into the subject.

  • Note: I am assuming that when you say "my client is a machine(Digi), which as a requirement has to use RSA encryption" you mean that it uses the SSL protocol. SSL and RSA are different things - it is possible to use SSL with - for example - Elliptical Curves instead of RSA, in the same way that it is possible to use pure RSA without SSL (with previously exchanged keys - pre-exchanged Keys - or a "Web of Trust" scheme). If my interpretation is wrong, please clarify the question further.

  • the authenticateAsServer and authenticateAsClient part is already done, the same case is the key exchange because of the RSA

  • @Enzotiezzi In this case, I’m confused: you already have a secure communication channel established, but still need to exchange keys?! What protocol is this that you are using? It has to post some reference, a link on the subject?

  • I let explain better, really left badly explained

  • i made this communication secure, but even so using the RSA encryption (algorithm that has 2 keys, a private and a public), I need to send this public key to my other end, so that it can encrypt with this key that I sent

  • the same way I need to receive the public key from the other end, to encrypt the information to send to her.

  • Sslstream - http://msdn.microsoft.com/pt-br/library/system.net.security.sslstream(v=vs.110). aspx

  • RSA - http://msdn.microsoft.com/pt-br/library/system.security.cryptography.rsacryptoserviceprovider(v=vs.110). aspx

  • @Enzotiezzi In this case, the communication is already confidential. It is not necessary - from the point of view of communication - to encrypt anything else, because it is already encrypted. You may have other reasons for adding an additional layer of encryption (e.g., if the client is sending something to the server indirectly - through another channel not protected by SSL), otherwise this additional key exchange adds zero additional security. Note: I am not questioning the question, you may have your own reasons for doing so; in this case, I will let those who understand better of C# answer.

  • 1

    yes, I also have the same point of view, but the specifications are telling me to do this, that’s the point.

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.