-1

I have a client-server structure, and to avoid sending the public key I was thinking about using a fixed key. What about this?

I am padding and using a random SHA-256 when encrypting. So, with the public fixed, an attacker can't use brute force to decrypt.

I have a Client side (Xamarin APP) and a Web Api server. I am already using SSL and i know thats enough ! But imagin that i cannot use SSL and i have to use async crypto. I have to: CLIENT- request publickey -> SERVER - generate public and private key -> CLIENT - Get the publickey and cripto, sending the cripto data -> SERVER - get the cripto data and decrypt.

Mcfer
  • 194
  • 1
  • 4
  • 15
  • I have to agree with @zaph here, that's definitely an important clarification. Can you also clarify what mechanism you are considering to store the private key(s) and to rotate it/them if necessary? – EJoshuaS - Stand with Ukraine Sep 21 '16 at 17:04

3 Answers3

1

That depends on if you have control of both the client and the server, how you're storing/fixing the key, and how difficult it is to deploy replacements to the client/server code. If it's not that difficult for you to do a re-deploy and you know that all instances of the client will be updated promptly I suppose you could just do a re-deploy if you ever needed to rotate the key.

However, if it's not that easy for you to do a re-deploy and/or you can't guarantee that all of the code will be updated promptly this could be a problem because you could be left without a method of rotating the key if your current one became compromised.

The other problem is that you don't really want to have all of your clients using the same private key, especially if you have a lot of clients. This increases the risk of your private key eventually being compromised and makes it more difficult for the server to verify the authenticity of individual clients. Additionally, this would create a single point of failure because if the private key is compromised, it would compromise the communications of all of the clients. If each client has its own private/public key, if its private key is compromised there's no impact on other clients so the damage would be much more contained.

Using per-client keys, compromising a private key could only compromise communications for a single client that occurred since the last key rotation; if, for example, you're rotating keys every 3 months compromising a key can never compromise more than 3 months of communication for a single client. (On average, it would compromise 1.5 months of communication for that particular client).

Incidentally, maybe I'm misreading your question but it's not important with public-key cryptography that the public key remain secret, just that you have a way of protecting the private key. The .NET Framework does have key containers for the purpose of safely storing the private key.

  • @zaph I meant if the clients are using the same private key, I might be misreading his question but I was assuming that he was going to hardcode the public/private keys of both the server and the clients. – EJoshuaS - Stand with Ukraine Sep 21 '16 at 16:51
  • @zaph it's definitely possible that I misread what the OP is doing here, my assumption was that both the client and the server have separate public/private key pairs and that they're both hardcoded (i.e. every single client was using the same hardcoded public/private key pair), correct me if that's wrong though. If my understanding is correct that would definitely be a security risk. – EJoshuaS - Stand with Ukraine Sep 21 '16 at 16:56
  • @zaph I do agree, the fact that there are a lot of clients doesn't intrinsically compromise the server's private key - however, if all of the clients have the same private key that would be a problem as it would make it more difficult for the server to authenticate clients, increase the probability that the key would be compromised, and increase the impact of the key being compromised. – EJoshuaS - Stand with Ukraine Sep 21 '16 at 17:00
  • 1
    @zaph So...i have a Client side (Xamarin APP) and a Web Api server. I am already using SSL and i know thats enough ! But imagin that i cannot use SSL and i have to use async crypto. I have to: CLIENT- request publickey -> SERVER - generate public and private key -> CLIENT - Get the publickey and cripto, sending the cripto data -> SERVER - get the cripto data and decrypt. – Mcfer Sep 21 '16 at 17:03
1

If you can protect the integrity of the client, it's safer to use a fixed public key than to magically bootstrap a secure connection from nothing.

Reading much into the question and comments, it sounds like you want to prevent a man-in-the-middle from decrypting messages from the client to the server. In order to do that, the client must be sure to use the server's public key, without getting tricked into using one generated by the man-in-the-middle.

If a public key is embedded in the client, and you have some mechanism to ensure that the key is authentic, you are safe.

In a PKI-based application, this is done by using certificates issued by well-known CAs, and verifying them before use. In a homebrew scheme, you could compute a hash of the client application, transmit that securely to the client (on a download page served via HTTPS, over the phone or written by a trusted party, etc.), and verify that the downloaded application's hash matches the authentic hash before running.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • If the public key is embedded in the client is not authentic the decryption will fail, hopefully that possibility is handled. – zaph Sep 21 '16 at 17:30
  • @zaph It won't fail after the MITM re-encrypts the message with the real public key after reading the message. – erickson Sep 21 '16 at 17:31
  • Perhaps I mis-understand "ensure that the key is authentic". Authentication is another issue. – zaph Sep 21 '16 at 17:33
  • But if the client is getting tricked into using one publick key generated by the man-in-the-middle, would not happen nothing because i create a cipher object for OAEP encoding. I think this is to avoid when it happen. – Mcfer Sep 21 '16 at 17:36
  • @MarceloCFernandes No, OAEP protects against something called an oracle attack, where an attacker can trick the server into telling whether a message was successfully decrypted or not. An oracle attack can be used to decrypt an RSA message, but it still takes on the order of one million guesses. – erickson Sep 21 '16 at 17:39
  • @MarceloCFernandes Maybe you mean that when you use your key to decrypt a message encrypted with the attacker's public key, it will fail because the padding is wrong. That is true, but that's not the purpose of padding, and it wasn't really designed to be relied on for message authentication. In any case, that won't protect you against an *active* man-in-the-middle who, like a proxy, can intercept messages and forward what he chooses. – erickson Sep 21 '16 at 17:45
  • @erickson But nothing protects 100% ! I want to minimize... If the OaepEncoding library use a RandomNumber and a Sha256 to encrypt and decrypt, how the man-in-the-middle will get encrypt or decrypt to see my data? And i also can pass a random hash – Mcfer Sep 21 '16 at 18:02
  • @MarceloCFernandes If the MITM substitutes his public key for yours, he can decrypt the message with his private key. This includes correctly removing the OAEP padding. He does it exactly like you would. Then he can use your public key to re-encrypt the message and pass it to you so that you don't know anything has happened. It's true that nothing protects 100%, but if you don't have any protection for the public key, you have 0% protection. – erickson Sep 21 '16 at 18:10
  • @erickson But he will not know my public key !! Just if i pass by querystring... But supposing that i pass the public key and he do what are you telling me, i cannot see how he will decrypt ! Just one key decrypt...and its mine and stored internall. Its not like A + B = C ... my code is based on this website...check the last example please [link](http://www.go4expert.com/articles/bouncy-castle-net-implementation-rsa-t24827/) – Mcfer Sep 21 '16 at 18:18
  • 1
    @MarceloCFernandes Public keys are *public.* Assume the attacker knows them. If you can keep the key secret from the attacker, just use symmetric encryption: simpler, faster, and more confidence about security. Anyway, I don't understand your point. The original question asked if this is safe; My answer, yes, it is, **if** you take some small precautions. But in your comments, you seem preoccupied defending the scheme against any suggestions for improvement or additional understanding. – erickson Sep 21 '16 at 18:26
  • @erickson No no... i just want to understand. Sorry if you fell bad... its because this is really confusing. – Mcfer Sep 21 '16 at 18:31
  • @MarceloCFernandes No problem then. I'm just trying to explain how some well-established and widely accepted schemes work, and how you might adapt them to a situation where you might not need "military grade" encryption. If I were tasked with spying on the messages from your client, and I had sufficient access (like I'm an employer, and client is run by misbehaving employee on my network, or I'm a government and can threaten ISP), I'd attack the public key. Some simple steps like verifying a hash of the downloaded client could thwart that attack though. – erickson Sep 21 '16 at 18:37
0

Embedding the public key in the client app should be fine and secure.

This assumes the public/private key pair are created once at app creation time, the public key is embedded in the app and the private key is kept on the server.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Funny that i am not finding nothing talking about this on the web. Do you have some article or website talking about this ? – Mcfer Sep 21 '16 at 17:18
  • The usual method is to use HTTPS. With HTTPS the public key is sent in a certificate to the client. This allows the client the ability to contact any server without the pubic key needing to be pre-shared. In you case you are simply pre-sharing the public key. – zaph Sep 21 '16 at 17:23