ERXCrypto thread safety, performance, and security
ERXCrypto thread safety, performance, and security
- Subject: ERXCrypto thread safety, performance, and security
- From: Allen Cronce <email@hidden>
- Date: Sat, 24 Jun 2006 12:42:57 -0700
Hi all,
I've been investigating using ERXCrypto for database encryption and have
some observations/issues. Apologies in advance to the general WO list
members for the somewhat OT nature of this post. If you don't care about
partial encryption of your database, then please ignore it.
Thread Safety:
The ERXCrypto implementation uses static Blowfish Cipher objects. But
Cipher objects are not guaranteed to be thread safe. First off, none of
the JCE providers use "synchronized" anywhere. Second, Cipher objects by
definition contain internal states that can change on a per encryption
operation basis.
The ERXCrypto implementation does not serialize access to these cached
Cipher objects. So if ERXCrypto's blowfishEncode and blowfishDecode
methods work in a multithreaded environment, it's because the current
security provider implementations of Blowfish for ECB mode don't have
any internal state when called with a single doFinal call. Unless I'm
missing something, this is potentially dangerous because it relies on
implementation assumptions that are outside of ProjectWonder's control.
I'd be interested in hearing from any developers who have used ERXCrypto
regarding what, if anything, they did to insure thread safety. Obviously
one solution would be to serialize access to the method calls. But
serialization can be expensive. I haven't done any performance tests to
see which is faster, creating a new Cipher object for each encryption
operation, or serializing access to a shared Cipher object.
Performance:
I was curious as to how Blowfish stacks up performance wise nowadays. So
I extended ERXCrypto to allow me to specify the cipher and key. I then
wrote an application that looped performing encrypt/decrypt operations.
I ran the app using jMechanic under Eclipse to obtain relative
performance numbers.
What I found was that using AES was about 41% faster than Blowfish for
the encrypt/decrypt operations on my development machine running Java
1.4.2 and Sun's security provider (not Bouncy Castle). This was not a
big surprise. Previous experience with compiled C security
implementations have shown time and again that AES beats the snot out of
older, less secure algorithms. Note that I only tested AES in ECB mode,
in part because I suspect that ERXCrypto only works in ECB mode due to
the threading issues raised above.
If you're interested in switching from Blowfish to AES with ERXCrypto,
there's pretty much no way to do it except to modify the code. Basically
you have to specify a cipher instance of "AES/ECB/NoPadding" when
creating the Cipher objects, a key algorithm of "AES" when instancing
the SecretKey, and a block size of 16. It would be nice if in the future
ERXCrypto allowed for the algorithms to be more flexibly specified,
perhaps by properties.
Note that using AES with ERXCrypto means that the data will be a little
bigger than with Blowfish. This is because ERXCrypto pads the data with
zeros to an even multiple of the block size, and AES has a block size of
16 instead of 8. ERXCrypto also doubles the string length by converting
it to a hex string. So you have to carve out enough space in your
database to hold the maximum string size rounded up to the nearest block
size (16 for AES), then multiply that number by 2 for the hex string
encoding.
Security:
ERXCrypto uses Blowfish in ECB mode. Even if we assume for the moment
that Blowfish is secure (which is a matter of debate best left for
cryptographers), the use of ECB mode can be problematic. The issue is
that ECB mode repeats the same encryption on a per block size basis. So
in the case of the ERXCrypto's Blowfish-based implementation, each block
of 8 bytes will be encrypted with the same key. That in turn means that
any patterns in the clear text on a per block basis would also be
visible in the encrypted data.
A better mode to use would be CBC, where each block encrypted affects
the subsequent blocks. That way, any patterns are completely obscured,
and a single bit change in the data affects the encryption of all the
data downstream of the change.
The problem with CBC mode is that it pretty much can't work with the
current ERXCrypto implementation because it has to use internal state to
chain from block to block. That would mean that ERXCrypto would have to
be changed to reset the Cipher on a per encryption basis and synchronize
access to the cached Cipher objects. Which is probably why they picked
ECB in the first place, although I couldn't find any such
rationalization in the comments or docs.
Of course, if you're only encrypting small runs of data, like credit
card numbers, and if you assume that your raw database is unlikely to
fall into the hands of hackers who are experienced with cryptography,
then ECB is probably OK. But if you're storing larger sized, highly
sensitive encrypted data, or if you're as paranoid as I am, then you
might want to consider alternatives.
Best,
--
Allen Cronce
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden