openresty / encrypted-session-nginx-module

encrypt and decrypt nginx variable values
http://openresty.org
195 stars 52 forks source link

An IV should be generated for each encryption #2

Open bdauvergne opened 11 years ago

bdauvergne commented 11 years ago

If you do not generate a per encryption IV your setup is not semantically secure, see http://en.wikipedia.org/wiki/Initialization_vector

agentzh commented 11 years ago

For encrypted sessions, it is fine for the authorized receiver to see the clear text of the data because we usually just put the user id and the expiration time into it. It's just important to prevent anyone from faking his new encrypted sessions. We have a similar situation as PGP (Pretty Good Privacy).

And yeah, for better security, one should update his IV (and key) in his nginx.conf periodically (maybe by some external cronjob tools).

Furthermore, we can also make ngx_encrypted_session automatically update the IV periodically (and keep a limited history of the most recently used IVs according to the session expiration time configured by the user). Patches are welcome here :)

I don't think we should generate a unique IV for every session because that way we'll have to store as many IVs as sessions on the server side, effectively defeating the whole point of this nginx module (where we do not have to store all the sessions on the server).

Thanks!

bdauvergne commented 11 years ago

IV should simply be transmitted with the encrypted content, no need to store it anywhere server side. In fact your encryption function should look like this:

Content -> concat(Random IV, AES256(Random IV, Content))

An HMAC signature would also be useful to prevent errors from invalid content.

Content -> HMAC(key, concat(Random IV, AES256(key, Random IV, Content)))

agentzh commented 11 years ago

That makes sense. Will you provide a patch for that? Thanks!

dndx commented 7 years ago

I came across this module while implementing my customized FIDO U2F auth module in NGINX. @bdauvergne got a valid point, in general IV should be re-generated from a secure random number generator (e.g. RAND_bytes()) for each encryption attempt to prevent attackers from inferring the relationships of cleartext by observing the resulted ciphertext. IVs can be transmitted in cleartext without any encryption without undermining the security of the cipher and because they are fixed size, it can be separated easily later. (e.g. always prepend IV before the ciphertext).

rcosnita commented 4 years ago

I contributed an initial version of the code which seems to work. The code also keeps backward compatibility with what is already implemented and the inclusion of the IV + signature in the response is enabled only by using a directive. It would be great if you can take a look over the pending PR.