Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is RIJNDAEL encryption safe to use with small amounts of text given to users?

I am thinking about making the switch to storing session data in encrypted cookies rather than somewhere on my server. While this will result in more bandwidth used for each request - it will save extra database server load and storage space.

Anyway, I plan on encrypting the cookie contents using RIJNDAEL 256.

function encrypt($text, $key) 
{
    return mcrypt_encrypt(MCRYPT_RIJNDAEL_256,$key,$text,MCRYPT_MODE_ECB,mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,MCRYPT_MODE_ECB),MCRYPT_RAND)); 
}

Which in use would produce something like this (base64 encoded for display)

print base64_encode(encrypt('text', 'key'));

7s6RyMaYd4yAibXZJ3C8EuBtB4F0qfJ31xu1tXm8Xvw=

I'm not worried about a single users cookie being compromised as much as I am worried that an attacker would discover the key and be able to construct any session for any user since they know what I use to sign the data.

Is there a way I can verify estimated cracking times in relation to the parameters used? Or is there a standard measure of time in relation to the size of the text or key used?

I heard someone say that the keys needed to exceed 256bits themselves to be safe enough to be used with RIJNDAEL. I'm also wondering if the length of the text encrypted needs to be a certain length so as not to give away the key.

The data will generally be about 200 characters

a:3{s:7:"user_id";i:345;s:5:"token";s:32:"0c4a14547ad221a5d877c2509b887ee6";s:4:"lang";s:2:"en";}

So is this safe?

like image 353
Xeoncross Avatar asked Oct 30 '10 19:10

Xeoncross


4 Answers

Yes Rijndael(AES) is safe, however your implementation is far from safe. There are 2 outstanding issues with your implementation. The use of ECB mode and your IV is a static variable that will be used for all messages. An IV must always be a Cryptographic Nonce. Your code is in clear violation of CWE-329.

ECB mode should never be used, CBC mode must be used and this why:

Original:

alt text

Encrypted with ECB Mode:

alt text

Encrypted using CBC mode:

alt text

like image 68
rook Avatar answered Sep 21 '22 09:09

rook


Avoid using ECB. It can reveal information about what's encrypted. Any two blocks with the same plaintext will have the same ciphertext. CBC would avoid this, but requires an IV to be generated or saved.

Avoid simply saving a key and IV. Generate a 256 bit master key using a cryptographically strong random number generator and save that into you application somewhere safe. Use that to generate session keys for use in encryption. The IV can be derived from the session key. When generating the session key include any and all available data that can be used to narrow the scope of the session key. (e.g. include the scope the cookie, the remote host address, a random nounce stored with the encrypted data, and/or a user ID if it isn't within the encrypted data)

Depending on how the data is to be used you may have to include a MAC. ECB and CBC are not designed to detect any changes to the ciphertext, and such changes will result in garbage in plaintext. You might want to include an HMAC with the encrypted data to allow you to authenticate it before taking it as canon. A session HMAC key must be derived from the session encryption key. Alternatively, you could use PCBC mode. PCBC was made to detect changes in the ciphertext, but its ability to do so is limited by the size of the padding, witch is dependent on the data that is encrypted, and not all crypto APIs will have it as an option.

Once you have gone so far as to include a MAC, then you should consider taking steps against replay attacks. Any time someone can resend old data within the scope of a session is a chance for a replay attack. Making a session key usage as narrow as possible without causing issues for the user is one way to thwart replay attacks. Another thing you could do is include a date and time into the encrypted data to create a window for while the data is to be considered valid.

In summery, protecting the key is just the tip of the iceburg.

like image 44
Lunatic Experimentalist Avatar answered Sep 21 '22 09:09

Lunatic Experimentalist


If you use a long key, I'd say the key was pretty safe. Some things to concern yourself with:

You are offloading data storage to the client. NEVER TRUST THE CLIENT. This doesn't mean you can't do this, just that you either have to treat the data in the cookie as untrusted (don't make any decisions more serious than what 'theme' to show the user based on it) or provide for a way to validate the data.

Some examples of how to validate the data would be to:

  • include a salt (so that people with the same session data don't get the same cookie) and
  • a checksum (so that someone who changes even one bit of the cookie makes it useless).
like image 31
Slartibartfast Avatar answered Sep 20 '22 09:09

Slartibartfast


Rijndael was renamed AES. Yes, it is safe to use.

That said, you should consider carefully what you put in the cookie. It depends on what you have available in the way of storage on your system, but you could simply choose a random number (say a 64-bit number), and store that in the cookie. In your server-side system, you'd keep a record of who that number was associated with, and the other details. This avoids encryption altogether. You use the other details to validate (to the extent anything can be validated) whether the cookie was sent back from the browser you originally sent it to.

Alternatively, you can use a different encryption key for each session, keeping a track of which key was used with which session.

Even if you go with straight encryption with a fixed key, consider including a random number in with the data to be encrypted - this makes it harder to crack using a known plaintext attack because, by definition, the random number can't be known.

like image 35
Jonathan Leffler Avatar answered Sep 21 '22 09:09

Jonathan Leffler