- I have a Java app, which among other things, needs to encrypt/decrypt binary files on the file system. I’m planning to use PBE (password based encryption) since the password will be entered by the user each time they use the app (it’s not stored anywhere).
- I don’t know if AWS KMS (key management system) or Google KMS can assist in any way, but it doesn’t matter since remote services are not allowed to be used for this project.
- Are there any Java libraries that will help me achieve my requirements, aside from directly interacting with the JCE API (java cryptography extension)? I’m not a security expert and don’t want to misuse the JCE.
- I’m also open to other ideas that don’t use a Java library, however, it must nicely integrate with my primary Java application.
Tink doesn’t support PBE.
The lead developer of Tink (Thai Duong) has stated as such. Thai does say it is possible to achieve using an internal API (AesGcmJce.java), however, he goes on: “This is not recommended because the subtle layer might change without notice”. I want a stable solution, so Tink doesn’t cut it.
There is an open github issue to add PBE to Tink.
Jasypt doesn’t seem secure.
If you want to know the details, read on, but it’s not required…
Jasypt is supposed to make PBE tasks easier, and the API is very simple, but the default parameter values it uses seem to be those which haven proven insecure (e.g., MD5 and DES). I can manually configure it to use more secure options but the very fact that its defaults are insecure makes me wonder what other aspects of the library are insecure.
For example, here are its default values when using the API:
- Encryption algorithm: PBEWithMD5AndDES
- No IV generator
- Random salt generator of 64 bits using SHA1PRNG (java.security.SecureRandom)
- KDF using MD5 with 1000 iterations
I can manually change the defaults to obtain the following configuration:
- Encryption algorithm: PBEWITHSHA256AND256BITAES-CBC-BC
- Random IV generator of 128 bits using SHA1PRNG (java.security.SecureRandom)
- Random salt generator of 128 bits using SHA1PRNG (java.security.SecureRandom)
- KDF using SHA256 with 1000 iterations
The API is super simple. Here’s how to instantiate the Java object which encrypts and decrypts binary data using the default settings (PBEWithMD5AndDES, etc):
StandardPBEByteEncryptor binaryEncryptor = new StandardPBEByteEncryptor(); binaryEncryptor.setPassword(password); byte cipherBytes = binaryEncryptor.encrypt(plainBytesArray);
In order to make things more secure I installed a lib called Bouncy Castle which adds many cipher algorithms for use by the JVM. Among the many options I chose PBEWITHSHA256AND256BITAES-CBC-BC. Similar to the code above, here’s how I instantiated the more secure configuration:
StandardPBEByteEncryptor binaryEncryptor = new StandardPBEByteEncryptor(); binaryEncryptor.setPassword(password); binaryEncryptor.setProvider(new BouncyCastleProvider()); binaryEncryptor.setAlgorithm("PBEWITHSHA256AND256BITAES-CBC-BC"); binaryEncryptor.setIvGenerator(new RandomIvGenerator()); binaryEncryptor.setSaltGenerator(new RandomSaltGenerator()); byte cipherBytes = binaryEncryptor.encrypt(plainBytesArray);
The library does have its own “stronger” encryptor classes (StrongBinaryEncryptor, AES256BinaryEncryptor, etc) but like I said, I’ve lost confidence in their software (unless you can explain otherwise).
Please help 🙂