Dave Syer (Migrated from SEC-2778) said:
Using the crypto module (AesBytesEncryptor in particular) requires the user to download JCE extension policy jars and install them in the JRE, which is a bit of a barrier to entry for some people. It would be good if there was a bouncy castle alternative, or a system property we can set or something (maybe already there)?
Michael Tecourt said:
Huge +1.
Aligning Spring Security crypto's defaults with the JRE's would really help.
According to Luke Taylor :
The current design of the crypto classes is intended to provide a simple set of canned utilities to enable best-practice for use in encryption, hashing, rather than a comprehensive set of classes which are fully configurable with any algorithm spec [...]
Unfortunately those users who do need _canned utilities_ to apply security best practices are the ones confused when it comes to installing add-ons to the JRE. It's especially confusing in Spring Boot where users particulary expect stuff to just work out of the box.
In practice, the following change would suffice in _class org.springframework.security.crypto.encrypt.AesBytesEncryptor_ :
public AesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator ivGenerator) {
// Hard coded "256" replaced by "128"
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), Hex.decode(salt), 1024, 128);
The following issues stem from the fact that the default helpers use AES with 256-bit keys while the JVM restricts it to 128-bit keys by default :
Dave Syer said:
Good points. However, I don't think defaulting to 128-bit keys could be described as "encouraging best practice", which is still definitely one of the main goals of spring security crypto. I don't have a better idea though. Oracle should just end the nonsense and package the JCE extensions with the JVM.
Michael Tecourt said:
Before Oracle ends the nonsense, "AES-128 provides more than enough security margin for the forseeable future" ... Is it still true 6 years later ?
https://www.schneier.com/blog/archives/2009/07/another_new_aes.html
@dsyer: As Michael Tecourt noted, 128 bit AES is still practically unbreakable (also according to more recent comments under Schneier's old blog post):
The fact is that I am writing right now in 2015, six years later, and there has been zero progress in showing AES is anywhere even close to be broken.
What progress has been made in 6 years that weakens AES in any practical way? Nothing. Zero. Well, except biclique attack that requires 2^88 bits of data (38 trillion terabytes) and weakens AES 128 to still impractical 2^126, Even that attack ism given amount of data required, is probably slower in practice than brute force.
One thing is that the default Spring Crypto behavior makes it difficult to manage JRE configurations (sometimes even impossible). There are enough people complaining about this problem in this issue tracker and on SO.
Another thing is that it might be straight out illegal in some cases, ref http://crypto.stackexchange.com/questions/20524/why-there-are-limitations-on-using-encryption-with-keys-beyond-certain-length/20525#20525 - I doubt Oracle will change anything about the JVM in the foreseeable future, especially in these times of Apple vs US and so forth.
You're preaching to the converted here. I'm not sure how we could downgrade the AES default without breaking existing apps, though, so there's a problem with switching to 128 as the default.
@dsyer I would be happy if there was just an easy way to use 128 bit. Perhaps another factory method in Encryptors.
@dsyer @tfnico I tend to agree the ship has sailed in terms of ensuring things work with existing applications.
However, I think we can allow better customization of the encryptors. Honestly, I'm not too keen on the approach that was taken in terms of Encryptors.standard, Encryptors.delux, etc. The problem is that cryptography needs to change but we must remain passive. This means that ideally I would be able to update the algorithms that are being used. However we cannot do that as things currently stand.
@tfnico If you would like to submit a PR to make AesBytesEncryptor public and provide some tests, I'd be happy to merge this for 4.1.
@rwinch +1 on the reasoning there.
As for PRs, my project is actually politically bound to do AES 256 (for no good reason really), so I won't get the work-time to improve anything. I'll moonlight it if I can, but would like to state that this is up for grabs if anyone else wants to have a go at it.
@rwinch @dsyer OK, so I managed to moonlight a little already. Quite late here, so go easy on me :)
I made a builder that can be used to construct an encryptor. It could be developed further to reflect the old Encryptions completely, or go a different way entirely:
I then re-shaped the test into using that builder so the tests will run wth 128 keyLenght on a JRE where there is no JCE, or with 256 as usual if the JCE is there.
The commit is here: https://github.com/tfnico/spring-security/commit/2e6318e26757bf66f7614373690861517746391b
On a half-related note, I put together a little desktop tool for playing around with the encryptors: https://github.com/tfnico/encryptomania
As you can imagine, having more configurable encryptors would make the tool look a lot more interesting :)
I would love to see a bouncycastle AES256 as default if we're weary of making AES128 default. The hard part is doing the AES256 properly with BouncyCastle Lightweight API, which is quite a bit lower level.
Sorry for all the force-push spam. On a different note, because of the performance optimizations in JCE, should we try to see if that's available, and if not, use the BC implementation for Encryptors.standard()?
@william-tran Thanks for the comment. We cannot make this the default because we need to ensure we are passive. Changing the crypto provider out from under people could possibly break FIPS compliance (i.e. JCE is compliant and BC is not AFAIK) for someone using the defaults and who just forgot to setup JCE on a new box.
Most helpful comment
@dsyer @tfnico I tend to agree the ship has sailed in terms of ensuring things work with existing applications.
However, I think we can allow better customization of the encryptors. Honestly, I'm not too keen on the approach that was taken in terms of
Encryptors.standard,Encryptors.delux, etc. The problem is that cryptography needs to change but we must remain passive. This means that ideally I would be able to update the algorithms that are being used. However we cannot do that as things currently stand.@tfnico If you would like to submit a PR to make AesBytesEncryptor public and provide some tests, I'd be happy to merge this for 4.1.