11

The team of developers I am part of is trying to develop a safe way to exchange sensitive data between a server and mobile devices.

We have come up with the following algorithm:

  1. Device generates private RSA key, and sends the public key to server.

  2. Server generates unique to user AES key and uses the RSA public key to encrypt it and send it back to device.

  3. Device gets the AES key. Uses it to encrypt password and username and sends it to the server.

  4. Server decrypts the username and password. If there is a match, the AES key is used for secure communication for X amount of time or until log-out. Else, the process must be restarted.

Is it safe enough? Are there ways it can be improved? What are the faults?

Edit: After reading the comments, what is a safer alternative and why?

Edit2: Ok, i get it. I won't use my own implementation, will find something already tried and proven.

Adrian Sicaru
  • 221
  • 2
  • 5
  • 46
    **PLEASE DON'T ROLL YOUR OWN CRYPTO / SECURITY**. What's wrong with [SRP](https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol) and [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security)? – SEJPM Jul 14 '15 at 12:04
  • 4
    We all are new to cryptography and creating our own crypto protocol seems like a good ideea – Adrian Sicaru Jul 14 '15 at 12:05
  • flaws: No MITM protection (*"Device sends public key to server"*), extreme workload (generating private RSA keys is expensive), Server needs to store password in *plain*, you don't even mention *authentication / integrity*. – SEJPM Jul 14 '15 at 12:06
  • 43
    *We all are new to cryptography and creating our own crypto protocol seems like a good ideea* - That shocked me alot. You don't know what to do in crypto and because of this you want to make your own protocol!? (hint: *really* bad idea) – SEJPM Jul 14 '15 at 12:07
  • 3
    Adrian - please read: http://meta.security.stackexchange.com/a/915/485 – Rory Alsop Jul 14 '15 at 12:10
  • To address your update, the best thing to do would be to hire a consultant that can figure out your needs and make recommendations. – mikeazo Jul 14 '15 at 13:00
  • In addition to what everyone else is saying, please enlighten me. What happens when you all move on to bigger and better things. Will this protocol receive ongoing support? If a weakness or flaw is discovered then can the company rely on you to address the issues? Is this going to be released into the wild (open-source) and receive continuous updates as community members strive to improve it? – MonkeyZeus Jul 14 '15 at 15:14
  • 7
    Also, keep this quote in mind: "If you think cryptography is the solution to your problem, then you don't understand cryptography and you don't understand your problem" - Roger Needham and Butler Lampson – mikeazo Jul 14 '15 at 15:40
  • @AdrianSicaru The folks at StackExchange really need to add the ability to downvote comments, just so that we can downvote "We all are new to cryptography and creating our own crypto protocol seems like a good ideea". It's a really, _really_ bad idea. – Mike Scott Jul 14 '15 at 19:26
  • RSA+AES is a good combination. But the protocol described in your question is not. You lack integrity and forward secrecy. – kasperd Jul 14 '15 at 20:24
  • @mikeazo Does that imply that cryptography is the solution to no problems? – user253751 Jul 15 '15 at 00:43
  • 1
    @immibis, I would say it is not a solution, only a tradeoff. It may be a good tradeoff, but knowing that really requires a good understanding of cryptography and the problem at hand. – mikeazo Jul 15 '15 at 02:16
  • Judging from the number of views, i guess many were too afraid to ask this same kind of question. – Adrian Sicaru Jul 15 '15 at 11:51
  • Not really. This question got a lot of views because it got into Hot Network Questions where users on different SE sites can go to this post and read (and vote) it.. – Andrew T. Jul 15 '15 at 12:19
  • For the moment i will stick to the beaten path, but for the future it would be interesting to try my own way, in the test environment. For fun at first and who knows, maybe one day something nice will develop – Adrian Sicaru Jul 15 '15 at 12:27

5 Answers5

35

All of the weaknesses in your protocol can be summed up as "use SSL" or even "use SSL, dammit !".

In more details:

  • All the protocol is of course vulnerable to impersonation, specifically the double impersonation that is also known as Man-in-the-Middle attack.
  • Similarly, if any of potential attackers that can eavesdrop on the line decides to do a modification of the data in transit, then he can, and your client and server will be none the wiser.
  • Experience shows that saying "encrypt all the data with that key" and then doing it correctly is awfully complex. SSL itself took almost 15 years to do that, and many implementations are still not up to it. Padding oracles, predictable IV, MAC verification timing, verified closure, protection against resequencing and replay of packets...

As an overall assessment: don't do that.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 2
    Surely you mean TLS and not SSL. [Wikipedia: Transport Layer Security: SSL 1.0, 2.0 and 3.0](https://en.wikipedia.org/wiki/Transport_Layer_Security#SSL_1.0.2C_2.0_and_3.0) "As of 2014 the 3.0 version of SSL is considered insecure..." "SSL 2.0 is deprecated..." "SSL 3.0 is deprecated..." – user Jul 14 '15 at 12:22
  • 25
    I use "SSL" to designate the family of protocols that goes from SSL 3.0 to TLS 1.2. The usual "SSL vs TLS" terminology is not good; see [this](http://meta.crypto.stackexchange.com/questions/544/should-we-still-use-ssl-as-tag-instead-of-tls/549#549) for more details. – Thomas Pornin Jul 14 '15 at 12:25
  • 1
    Fair enough, there. But in this particular instance, maybe you want to be slightly more explicit and say "use a modern/standardized variant of SSL"? Anyway, minor detail in the grand scheme of things. – user Jul 14 '15 at 12:28
  • Using SSL doesn't address the question of how to validate a password. As we know password validation can be done very insecurely, even if the SSL encrypted communication isn't broken. For a new systems which are not bound by backward compatibility requirements I would recommend using a password validation method in which the server never sees the password in clear. Your answer could be improved if you would include a recommendation of a standard password validation method with that property. – kasperd Jul 14 '15 at 20:21
  • 1
    _Seeing_ the password in clear on the server side is not an issue as long as there are guarantees that the client is talking to the genuine server (the server certificate in SSL is used for that), _and_ the server computes a strong password hash on incoming passwords, to compare with a stored value (the usual recommendation for that password hash is bcrypt, NOT any homemade construction, of course). A more advanced protocol would make the client compute the bulk of the bcrypt value, but this would work only with computationally powerful clients. – Thomas Pornin Jul 14 '15 at 20:28
  • @ThomasPornin That is true assuming that servers are never compromised and users never reuse passwords. Both assumptions are known to not hold in practice. When users are reusing passwords and servers can be compromised, it is a weakness to let the server see the password in clear. – kasperd Jul 14 '15 at 21:29
12

No this protocol isn't safe.

As already mentioned in the comments:

Don't roll your own crypto. Chances are you're getting it wrong. Especially if you admit that you don't really know what you're doing.

First, you seem to have standard problems for which there are already standard protocols, which have nice properties and security proofs. The protocol for the data transmission should be TLS v1.2 (or newer). You should use a library (like NSS, GnuTLS or OpenSSL for this). For password authentication the best choice you have is to use SRP or TLS-SRP. However if you really can't afford SRP (which should be your first choice) you can still follow this paper.
So far for the improvements.

Now for the flaws of your protocol:

  1. It's vulnerable to Man-in-the-middle attacks. If an attacker sits in-between the device and the server, he can fish the public key and replace it with his own. In response he'd know the AES key and could decrypt all the data.
  2. You don't mention integrity / authenticity of the data. It sounds like you want to use ECB mode for AES (which you really don't want to use), you'd be a lot better off with AES-GCM for the bulk-encryption. You also don't mention how RSA is to be used, RSA-OAEP should be your choice (and not textbook RSA). However I assume you'd have done this with your implementation.
  3. You put a really large workload on the device. The device needs to generate a new private RSA key with every connection, which is a highly computing-intense task. You should rather consider using ECDH key exchange.
  4. For the verification of the passwords to work, you either need the server to store the passwords in plaintext or to hash them himself, which may enable DoS attacks on the server. And in case a man-in-the-middle attack takes place, the plain passwords will be revealed to an attacker, which may cause serious harm to your users (as they may re-use their passwords across sites...)
SEJPM
  • 9,500
  • 5
  • 35
  • 66
  • As for (4), I'm not sure which is worse: storing passwords in plain text, or (at least in the eyes of an active attacker essentially, and certainly for the server) sending them in plain text... – user Jul 14 '15 at 12:25
  • @MichaelKjörling, added the reovery of passwords in case of an active attack. Thank you. – SEJPM Jul 14 '15 at 12:31
5
  1. Device generates private RSA key, and sends the public key to server.

  2. Server generates unique to user AES key and uses the RSA public key to encrypt it and send it back to device.

  3. Device gets the AES key. Uses it to encrypt password and username and sends it to the server.

Anonymous key exchange.

There is no authentication. Your key exchange is encrypted, but not authenticated. This is bad.

If there is an active Man-in-the-Middle, then you have no way of detecting this. This active MitM can just pretend to the client that he is the server. And pretend to the server, that he is the client.

-> Don't do it. @SEJPM is right with his comment. Use established crypto systems. Like TLS with certificates or TLS with SRP.

StackzOfZtuff
  • 17,783
  • 1
  • 50
  • 86
-1

that's the way i use to do rsa /aes combination

  1. client generate a random aes key
  2. use the aes key to encrypt the data you need (rsa take longer time and have length limitation, so better use aes to do encrypt)
  3. use the public key to encrypt the aes key
  4. pass the encrypted data and the aes key encrypted by rsa public key to server
  5. when server receive, decrypt that aes key by private key and then decrypt the attached data by the decrypted aes key
chings228
  • 99
  • 1
-4

It's pretty good but I would do this in an easier manner which I think is more secure and similar to what you thought of.

Since the communication is client-server:

  1. Mobile client generates key using PRNG
  2. Client sends step 1 key using server public key (only server has private to decrypt)
  3. Client encrypts user/password with step 1 key and sends to server
  4. If user/password are verified - server returns new key for data encryption, encrypted with step 1 key

-. Please do step 2 - 4 over TLS if possible

--. Change keys every X iterations (enforce on client and server)

---. Client must trust server certificate to prevent MITM/impersonation

Erez
  • 333
  • 1
  • 2
  • 5