2

The following scenario:

We have a HTTP (not HTTPS, so unencrypted) server which contains an open (RSA) public key. The general sharing of the public key should not be a problem since it is the public key. My concerns are more about a MITM (man in the middle) attack. So let's assume that in our scenario the servers in the local network are well secured and there is no attack at the endpoints.

Now my question would be:

Is a MITM attack possible in the transfer through the public internet?

If not, would it be theoretically possible to have encrypted data transfer via HTTP with RSA encrypted POST requests and encrypted replies?

scolastico
  • 23
  • 3
  • I'm so confused. If the traffic is not secured, then, yes, a mitm attack is possible. How does the public key come into it since you say that the exposure of the key is not a problem anyway? – schroeder Nov 12 '21 at 09:40
  • Can you encrypt data before sending over an unencrypted line? Of course. But not if you are trying to secure at the *network* level. You can't secure a lower level of the stack by adding controls to the higher levels of the stack. – schroeder Nov 12 '21 at 09:42
  • @schroeder I mean, the first key exchange via HTTP would then be insecure - everything that follows is then secured via RSA. To be more precise, I want a service that can be set up quickly without having to request an SSL certificate first. There are no passwords or highly secure information exchanged in general, but I still want to encrypt the whole thing a little. Because of the first unsecure key exchange I am not sure if one could not hook in exactly there and then start a MITM attack. – scolastico Nov 12 '21 at 09:45
  • A small addition: I am of course aware that only the body of the http requests would be encrypted but since there is no information in the header (like cookies) this is not really bad. – scolastico Nov 12 '21 at 09:50
  • 1
    Ah, then this is a X/Y problem. You are trying to solve one problem, but asking about another thinking that the answer to that will solve the true problem. 1. Let's Encrypt solves your certificate problems. 2. you have a misunderstanding about how RSA encryption works and the impact of the public key being known. – schroeder Nov 12 '21 at 09:51
  • You can replicate the basic process of TLS at the application level. Take a look at how the TLS handshake works, because that, too, happens without encryption... – schroeder Nov 12 '21 at 09:52
  • @schroeder Of course lets encrypt is easy to set up and so on I know and use it a lot. But as I said, it is only about "unimportant" information in the body to encrypt a little. And the most important thing is that it has to work fast and without a domain. So with the prerequisite lets encrypt is already out because there a domain is needed. Also regarding the disclosure of the public key: Each instance gets its own public key generated accordingly it is also very unlikely to get the first public key again, except with a MITM attack in which another set of keys is in play. – scolastico Nov 12 '21 at 10:01
  • And last but not least all public keys are regenerated regularly so even if someone tries to decrypt the public key and get the private key it won't do much good. I will have a look at the tip with the TLS handshake. Thank you. – scolastico Nov 12 '21 at 10:02
  • ... you can't "decrypt the public key to get the private key". And it should *never* matter that the public key is known. As you said, it is *public*. I really think that you need to understand how this all works. – schroeder Nov 12 '21 at 11:34
  • Is the question about sharing the RSA key (title), or about using the RSA key to encrypt/sign something? – Paŭlo Ebermann Nov 13 '21 at 01:17

1 Answers1

7

TL;DR: No. "Secure" is not a binary property, and this is better than nothing, but it's very vulnerable to MitM.


What you're describing is effectively unauthenticated opportunistic encryption. It's not a terrible idea - it is better than plain text, in that it will defeat a passive eavesdropper - but it's not great. It would be trivial for a network attacker to defeat, either by substituting the public key for their own, or by modifying the HTML/javascript (assuming a browser-based client) that retrieves the key and performs the encryption. Even if the attacker misses the start of the communication and thus can't interfere with the key exchange, they can forcibly reset the communication between client and server, probably causing the page to get reloaded and giving themselves a new chance.

Incidentally, if you really think this is worth it, at least try to do it right. RSA is an OK but not great choice for exchanging a symmetric key but you definitely shouldn't try to encrypt the actual requests with it, and you couldn't even encrypt the responses with it unless the client also generated and send a public key. Instead you should use a hybrid cryptosystem, where a symmetric key (or secret that can be used to derive a key) is exchanged, and then further communication is secured by symmetric encryption (with either HMACs or AEAD for integrity too). And, if you're going to do hybrid crypto, it makes more sense to use Diffie-Hellman (or better yet, elliptic curve DH) for the key exchange, as the parameters are much lower-cost to generate than a strong RSA key so you can get forward secrecy and good cryptographic strength at a reasonable cost. ECDH is supported in the Web Crypto API, so you don't have to write any cryptographic primitives yourself.

CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • Thank you for your detailed answer. As a quick addendum: It is an API that is not called by normal browsers but only by two programs that are tuned to each other. So as you said, both logically generate a key set. In addition, the key local is stored by both for the duration of the session and then deleted by both. – scolastico Nov 12 '21 at 10:05
  • It's an API? Yeah, I *really* think you have a major X/Y Problem here. There are solutions to your problem, but you need to state the *core problem* not the problem with your proposed solution to the problem. – schroeder Nov 12 '21 at 11:38
  • As I said before, it is simply a matter of two programs communicating with each other in a "reasonably secure" manner (with the requirements already mentioned). I just don't feel like getting into the topic of tcp/udp connections and how to encrypt them. Instead I just had the idea to start a web server via the available libaray and check the body of post requests etc before and decrypt/encrypt them. The whole thing is not very elegant but is functional in my eyes. – scolastico Nov 12 '21 at 12:05
  • +1 Excellent answer by CBHacking as usual. OP, you mention `two programs that are tuned to each other`. I'm not sure what you mean by `tuned`, but if it's possible for you to pre-share keys between the two endpoints, then this greatly simplifies the problem, and eliminates the possibility of an MITM attack. – mti2935 Nov 12 '21 at 13:06
  • 3
    Having said that, it really sounds like you are re-inventing the wheel here. Crypto is tricky, and one oversight can lead to a disastrous security vulnerability (as we've seen many times). If you can, use a tried and true protocol like IPSec, SSL/TLS, etc., instead of rolling your own crypto. See https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own for some interesting reading on this subject. – mti2935 Nov 12 '21 at 13:08