I need to encrypt some details for the users of my application (not the password, I am using bcrypt for that), I need to access the details at some point in the future, so i need to be able to decrypt these details, to do that, I have the following class in my spring boot application, my question is how to secure the password used to encrypt the text?
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
public class Crypto
{
final static String password = "How_to_Secure_This_Password?";
public static String encrypt(String textToEncrypt, String salt)
{
if (textToEncrypt != null && !textToEncrypt.isEmpty())
{
TextEncryptor encryptor = Encryptors.text(password, salt);
String encryptedText = encryptor.encrypt(textToEncrypt);
return encryptedText;
}
return null;
}
public static String decrypt(String encryptedText, String salt)
{
if(encryptedText != null && !encryptedText.isEmpty())
{
TextEncryptor decryptor = Encryptors.text(password, salt);
String decryptedText = decryptor.decrypt(encryptedText);
return decryptedText;
}
return null;
}
}
From my research so far I can suggest the following solutions:
1- Get the password from a properties file and use Spring Cloud Config for the encryption/decryption feature for the properties file (values prefixed with the string {cipher}), a good starting point is here. I don't like this solution as I don't need the client/sever config structure, and I don't feel good about using it for the sake of one feature only, I believe Spring framework should have similar feature.
2- Use Jasypt library, or its 'unofficial' support for spring boot from here. Again, not sure if the problem is a matter of encrypting this password in a properties file?
3- use the Vault which looks built for something similar to what I need here (API keys, secrets etc...) but it is too much overhead to build, maintain, and integrate ...
My argument here is that if an attacker was able to access my database machine/s then he is most likely will be able to access the application machine/s which means he may be able to revers-engineer the class and will be able to decrypt all the details which I want to secure! I feel confused here, what is best practice and the industry standard here?
The best solution so far is to use Spring Cloud Vault as I am already using spring boot, it can offer more than securing this password, in fact it can secure the password for many API keys, databases etc (it is RC release at the time of writing) .. however, I am not convinced yet that this is the ultimate solution as my application still need to authenticate against the Vault, but I have to say that this is done in a more advanced way and gives a one step further than keeping passwords in config files ...
The issue is chicken and egg problem, and it turns out that SO has so many many similar questions for similar scenarios (saving database password in config, hide it in code, hid password in PBE store etc etc).
This well explained by Mark Paluch in his getting started article
Encrypted data is one step better than unencrypted. Encryption imposes on the other side the need for decryption on the user side which requires a decryption key to be distributed. Now, where do you put the key? Is the key protected by a passphrase? Where do you put the passphrase? On how many systems do you distribute your key and the passphrase?
As you see, encryption introduces a chicken-egg problem. Storing a decryption key gives the application the possibility to decrypt data. It also allows an attack vector. Someone who is not authorized could get access to the decryption key by having access to the machine. That person can decrypt data which is decryptable by this key. The key is static so a leaked key requires the change of keys. Data needs to be re-encrypted and credentials need to be changed. It’s not possible to discover such leakage with online measure because data can be decrypted offline once it was obtained.
.......
Vault isn’t the answer for all security concern. It’s worth to check the Vault Security Model documentation to get an idea of the threat model.
Ironically enough, Vault storage backend needs to be configured with plain text passwords for most cases (MySQL,S3, Azure, ... I am not accepting this as an answer to my question yet, but this is what I have found so far, waiting for more input from fellow SO contributors with thanks!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With