1

I currently have a group of web-services exposing interfaces to a variety of different client types and roles. Authentication is handled through a public/private key pairs (RSA) only to verify the URL as signature in the HTTP Header.

At this time the HTTP Body is not encrypted (I use a private/public key of 2048 bit which allows me to encrypt only small amounts of information), so RSA is not enough safe because the server can no longer prove to himself that there's not a Man-In-The-Middle. I can encrypt also the HTTP body, but what about performance?

My question is: what techniques are recommended to prevent a MITM attack in this case?

user65567
  • 671
  • 2
  • 6
  • 9
  • 1
    You seem to believe there may be a performance problem. Have you considered simply testing to see if that will be the case? – Zoredache Feb 25 '11 at 17:05
  • @Zoredache I didn't tested that yet, but I think it is a problem with a lot of authentications. – user65567 Feb 25 '11 at 17:13
  • I'm not seeing where there's a (easy) MITM attack in here, unless neither side is authenticating the Cert against a CA. The key length also has nothing to do with encryption; they public/private keys are used to establish the session key, they don't actually encrypt the traffic (unless you coded your own custom system). – Chris S Feb 25 '11 at 17:32
  • @Chris S "What techniques are recommended to prevent a MITM attack in this case?" refers to the possibility to change the HTTP body content (the important header values are signed). Public/private keys can be used to encrypt the HTTP body, but, since I need to encrypt a lot of data, 2048 bit are not enough to encrypt that (I get errors like 'OpenSSL::PKey::RSAError (data too large for key size)'). – user65567 Feb 25 '11 at 17:46
  • 1
    Why on earth wouldn't you just SSL encrypt the entire communication stream between the client and your server? – NotMe Feb 25 '11 at 18:35
  • 1
    RSA is usually only used for the initial handshake and authentication. The encryption of the data transfer itself is usually done using a block cypher like AES. A block cypher is much faster than RSA and should be able to do >100MByte per second. –  Feb 25 '11 at 18:36

3 Answers3

2

There is absolutely no point in using HTTPS if you don't encrypt the entire authenticated session. If any point you transmit the session id over an insecure channel then an attacker can use this to authenticate (Like Firesheep). Further more you are violating OWASP a9.

From a performance perspective the most expensive part of SSL is the initial handshake. This is cached and there for only done once per client.

Another thing to keep in mind is that if you want to stop SSLStrip style attacks then you should set the STS-Header.

Rook
  • 2,655
  • 6
  • 27
  • 35
  • The fact is that I need to trasmit not only the session id, but also other datas that, using a public/private key pairs at 2048 bit, is not possible to encrypt. If I use 4096 bit, it is possible (for now), but what about the performance? P.S.: I updated the question! – user65567 Feb 25 '11 at 17:01
  • 1
    @user502052 When i say the entire session i mean **ALL DATA** transmitted between you and the client from the moment you issue a set-cookie to the moment you destroy that session. – Rook Feb 25 '11 at 18:16
2

If your goal is only authenticity (and not confidentiality), the signature in the header, either from the client or server, or in both directions, can be used to verify that the bits received are from the sender.

Note that if the signed content does not have a timestamp that is checked, it is vulnerable to simple replay which could enable someone in the middle to perform some function or masquerade as the other side indefinitely.

The error "data too large for key size" partly occurs because direct RSA encryption/decryption is computationally intensive so the implementation is not designed to process bulk amounts of data. The actual limit is related to the cryptographic strength guarantees the algorithm provides. Allowing a large, low entropy payload would weaken it.

To avoid this error, you need to use a message digest algorithm that performs a one way hash like MD5 on a larger set of bits, such as the HTTP POST body, and then encrypt the fixed-size digest result using RSA encryption. The encrypted hash is essentially a digital signature. The receiver side then decrypts, computes the hash result of the body, and compares the hashes to verify the signature.

Note that if a session key is available because encryption is also being used, then the hash of the body could be simply be encrypted with that shared symmetric key instead of doing the more costly RSA encryption. This is termed a message authentication code (MAC) and is not as strong as a signature.

1

Go for tried and proven solution: use HTTPS with mutual authentication, as a bonus encrypt entire session. HTTPS performance isn't an issue unless your client running on TI calculator. Google using it for entire Gmail, this should be a good example.

blaze
  • 111
  • 2
  • What do you mean with "HTTPS with mutual authentication" and "TI calculator"? – user65567 Feb 25 '11 at 17:32
  • HTTPS performs mutual authentication when there are server certificate and client certificate used. This gives you protection from MITM attacks on both ends. TI calculator is just an example of very low computational power device :) –  Feb 25 '11 at 17:47
  • Ok. In my case I refer to the possibility to change the HTTP body content (the important header values are signed). Public/private keys can be used to encrypt the HTTP body, but, since I need to encrypt a lot of data, 2048 bit are not enough to encrypt the data (I get errors like 'OpenSSL::PKey::RSAError (data too large for key size)'). – user65567 Feb 25 '11 at 17:55