Re: [OT] Is calculating an MD5 hash of a Rjindael encrypted block and it's key insecure?
Richard Atterer wrote:
My solution is a mod_perl module, that catches every request before the
authentication module and supplies the credentials automatically. This
works with ANY apache authentication modules using basic authentication.
This strikes me as a weird solution. What's wrong with setting the cookie
lifetime higher, so that people only need to log in e.g. once a day? Hmm,
presumably the web application is closed-source or un-hackable due to other
No, not at all. The apache authentication Module used is auth_ldap,
which in turn authenticates against a Windows 2000 AD Server. As
auth_ldap uses basic authentication (which basically means, that the
user has to enter his / her login / password everytime) this solution
saves these credentials (username / password) encrypted in a cookie.
- No more credentials that are sent in plain over the internal network
(which is the case if you use basic authentication), except for the
- No more logons every time you open the browser window
- Great flexibilty in choosing the REAL authentication module for apache
(any module using basic authentication can be used)
The cookie has a limited lifetime, is bound to the client's IP address
and is AES256 encrypted, with a server side stored encryption key.
If I understand this correctly, you have one central server-side AES key
which never changes. From a security design POV, this is bad - a malicious
user might be able to turn your Apache module into an oracle; he can supply
a huge number of fake user/password strings and analyse the encrypted
cookie's contents, with an intent of cracking the central key.
That's actually true. Of course there is more information encrypted than
just the credentials themselves. Actually the server key could be
changed on a regular basis. But you're right, that by knowing the
content of the encrypted cookie, one could deduct the password... But I
think this is not possible, because of this:
The block size of the data to be encrypted has to come in chunks of 16
bytes. I always append random numbers to the credentials, ip and time
strings to the next 16 bytes before encryption. Like this, the attacker
cannot know or guess all of the content of the encrypted data, can he?
An alternative approach to the whole problem could be to use a server-side
database of user/password data. The cookie could contain just a random
string of bits to reference the right database entry.
I thought about this, but is storing plaintext user / password data more
I discovered, that if I changed this encryption key, the module would not
return, as it could not decypher the credentials. Furthermore someone
could send an invalid cookie which would cause some DoS attack. So I
added a checksum over the encrypted credentials and the key itself. This
checksum has the form of an md5 hex checksum and is checked before the
decyphering of the credentials takes place.
Again, this feels wrong if I think of abuse of the server as an oracle.
Maybe consider encrypting the checksum with the rest of the data, i.e.
$c = encrypt( $s . md5($s) )
The trouble is, as far I figured out, that Crypt::Rjindael does not
return, when you try to decrypt an encrypted string that's, a. damaged
or b. encrypted with a different key. Don't know why. I guess I have to
check this again, because getting rid of the checksum, would be the best
For all practical purposes, this should be fine. For example, there are far
easier attacks if I were to have access to your intranet, like intercepting
the traffic between my victim users and your server via ARP poisoning,
persuading them to try logging on on my machine, or just bribing them. :)
Well, yes, that's for sure ;-)
But with my nitpicking-security-paranoia hat on, the solution is not ideal.
This is important because $s and $c get stored in the cookie.
Why $s? Surely you'll only store $c in the cookie, otherwise there's no
point in encrypting the data.
Ahem, well $s is encrypted and $c is only a md5 checksum for $s and $k.
But perhaps there is a better way to build a checksum of the encrypted
data / key.