5

A company whose services I'm trying to integrate uses this protocol:

  1. An AES key is embedded in an Android library.
  2. To authenticate itself, the library sends a SHA1 hash of the key over plain HTTP.
  3. The response contains an RSA public key encrypted using the same AES key.
  4. A temporary AES key is generated on the client.
  5. The temporary AES key and the sensitive data are encrypted with the RSA key and sent over plain HTTP.

Their excuse for not using HTTPS is that they believe they'd have to pay for a signed certificate on every mobile device they support rather than just on their server. They also believe that HTTPS adds too much network overhead for use on mobile devices. Oh, and their system is "more secure than HTTPS" because they're using longer AES keys. Did I mention this is being used for credit card processing?

I'm trying to convince them that this is utterly insane. Can anyone point me to a clear, concise explanation that's intelligible to PHBs? (Or which I could bring to the unemployment hearing if I get fired for rocking the boat?)

  • According to the design, the client needs to check on the server's public key for the private exchange. How is that different than HTTPS? Unless they were hoping that by encrypting the public key (?!) the client wouldn't need to check with the CA ... – schroeder Jul 22 '14 at 14:24
  • There is no CA involved. Remember, they think they'd have to buy a cert for every client. So the difference from HTTPS is that there is no authentication of the server's public key, and a MITM attacker could easily replace it with their own. – Kevin Krumwiede Jul 22 '14 at 17:00
  • Your development team should not be rolling their own encryption processes at all in any event, but certainly not when they don't understand PKI 101. Your recommendation should simply be to follow industry standards. You just have to prove the costs of such a scheme are no more than their proposed solution. – schroeder Jul 22 '14 at 18:57
  • Agreed wholeheartedly. But it's not our own development team; it's another company that we've hitched our wagon to. And it's always a fight to get anyone to consider any costs except the immediate ones. – Kevin Krumwiede Jul 22 '14 at 21:21
5

Yeah, if you are describing it accurately this is completely broken, to the point of useless.

The initial AES key is compromised by being in the app, anyone with the app has access to the AES key. If this is global, then it is well and truly screwed, if it is unique to each application, there may be a small sliver of hope.

The SHA-1 is completely replayable. You mention no salt, but even if there is a salt, the attacker can replay it against a legit client as a MitM and then respond validly to appear as the client to the server.

The server would then provide the attacker with the public key, in encrypted form, which isn't particularly useful to the attacker, but it is also the public key... it is supposed to be public. Having it private offers nothing. If the client was ever compromised (or any client if the AES key is global), then the AES key is leaked by the application and the public key is also available to the attacker.

Additionally, if the AES key is compromised, the attacker can send a public key of their choice since the client has no way to verify the RSA public key.

An AES key being generated on the client is a decent enough idea, but so far, there is nothing to prevent the attacker from generating their own AES key. Additionally, they could likely provide the client with their own public key so they can also fool the client.

Why is the data being encrypted with the RSA key? What is the point of the temporary AES key then? Is it really completely unused? Encrypting long data with RSA is generally considered less secure than using symmetric encryption since it is requires more work to process and may have other security implications, the norm is just to exchange a symmetric key and use that for data exchange.

In short, the system is completely useless.

It would actually be far more useful if they simply embedded the public key of the server in the application and used that to have the client generate an AES key and exchange that for session communication. It wouldn't validate anything about the client itself, but that could be done through passwords or other tokens after the session is initialized. At that point you are pretty close to just using a self signed HTTPS though, but it could be used as a custom implementation if HTTPS isn't an option for some reason (such as not being able to add a trusted root certificate on the client devices.)

4

Well, the AES key embedded in the library is completely useless, and there seems to be no validation of the server side. I see many problems with this scheme.

  1. Anyone with access to the Android library can extract the AES key.
  2. Sending a hash of a static value over plain HTTP is the same as sending a password over plain HTTP. Anyone can grab it from passive observation, so there's no authentication of the client.
  3. There's no authentication of the server, so if I get access to one client (and thus can steal the static AES key) I can MITM any client, send my own RSA key, and read/modify/tamper all of the traffic.

You don't mention how the AES is implemented (what mode, how the IV is generated, etc.) in what mode/padding the RSA key is used (if used unpadded, aka "textbook RSA", it's even more broken).

You said this is used for credit card processing, and while I'm not a PCI expert, I'm pretty sure this wouldn't pass PCI compliance.

  • Your first point was the one that instantly jumped out at me, but the others are also frightening. It occurred to me that if the original AES key hard-coded in the library were instead a RSA public key and they skipped straight to step 4, the system would be reasonably secure as long as the client's copy of the key is protected from tampering. I'm going to try to convince them of this. It should seem like a trivial change to the PHBs, and it's probably more constructive than my initial incredulous reaction. – Kevin Krumwiede Jul 22 '14 at 5:08
  • The funny thing is that from a PCI perspective this doesn't violate the DSS standards. Only if a QSA cared enough to dig into whether the design was providing effective security would this be flagged as a potential violation. – PwdRsch Jul 22 '14 at 15:45
  • @PwdRsch - well, technically it would be a violation, but a QSA is likely not going to catch it. You can fill out the QSA saying it is secure if you believe it is, but any competent audit would reveal that it is not secure and thus fail PCI-DSS. But yeah, it wouldn't surprise me at all if they claimed it was PCI compliant on their self assessment. – AJ Henderson Jul 24 '14 at 4:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.