I'm going to respond quite generally, since I'm not familiar with SslStream
(or even C # in general), but I think there are some misconceptions to this question that I can help to clarify.
The idea behind using a secure communications channel is that all content exchanged by that channel is protected (confidential, authenticated, unbroken). If that were not true, then there would be no point in using a SSL Stream - that would be enough if you simply used a Stream ...
In this way, the steps required to ensure the security of a channel ("handshake", or handshake ) are external to use that channel. It does not make sense for you to use SslStream
itself to send things like the encryption key, because at the time that stream is "usable" it assumes that hanshake (and therefore key exchange) has already been done successfully.
His 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 the handshake in the library's own classes. The correct way to use a SslStream
is to use your own methods to do the key exchange (and handshake protocol) and only start transmitting data through it when that process is completed successfully. .
Opening a parenthesis: Second the documentation , the class itself ensures that it remains unreadable until the handshake is not completed successfully:
SslStream :: CanRead property
Gets a Boolean value that indicates whether the underlying stream is readable.
true if authentication occurred and the underlying stream is readable; if not false .
As for the correct way to do this handshake , I'll leave it to those who understand C # better. A quick look at the documentation suggests the method AuthenticateAsServer
, and its variants. Which brings me to the last misunderstanding:
So I have to do a public key exchange between client and server.
It is not a exchange of keys that you need to do, but rather a certificate exchange . 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 assured that no eavesdropper will be intercepting the communication and reading its contents. But he can not be sure who he is communicating with.
A fake server (eg, a Man-in-the-Middle attack >) could send its key to the client - instead of the actual server key - in order to get the client to communicate with it thinking that it is communicating with the real server. Similarly, he can send his key to the real server, passing it through the client. In the end, instead of the communication being:
client real <----> server real
it will be:
client real <----> server falso, também client falso <----> server real
What destroys all the security guarantees that the SSL protocol would in principle give you. The solution (one of the solutions, though 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 an identity signed by a trusted third-party ) - established by mutual agreement.
A complete description of what a certificate is and how to use it correctly (sometimes only the server uses, sometimes the client too) would be too extensive for this answer, so I suggest you better inform yourself about how it 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 go deeper into the subject.