Securing a Password in a Properties File

Securing a password in a properties file

Sample Image

Jasypt provides the org.jasypt.properties.EncryptableProperties class for loading, managing and transparently decrypting encrypted values in .properties files, allowing the mix of both encrypted and not-encrypted values in the same file.

http://www.jasypt.org/encrypting-configuration.html

By using an org.jasypt.properties.EncryptableProperties object, an
application would be able to correctly read and use a .properties file
like this:

datasource.driver=com.mysql.jdbc.Driver 
datasource.url=jdbc:mysql://localhost/reportsdb
datasource.username=reportsUser
datasource.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)

Note that
the database password is encrypted (in fact, any other property could
also be encrypted, be it related with database configuration or not).

How do we read this value? like this:

/*
* First, create (or ask some other component for) the adequate encryptor for
* decrypting the values in our .properties file.
*/
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("jasypt"); // could be got from web, env variable...
/*
* Create our EncryptableProperties object and load it the usual way.
*/
Properties props = new EncryptableProperties(encryptor);
props.load(new FileInputStream("/path/to/my/configuration.properties"));

/*
* To get a non-encrypted value, we just get it with getProperty...
*/
String datasourceUsername = props.getProperty("datasource.username");

/*
* ...and to get an encrypted value, we do exactly the same. Decryption will
* be transparently performed behind the scenes.
*/
String datasourcePassword = props.getProperty("datasource.password");

// From now on, datasourcePassword equals "reports_passwd"...

Spring Boot how to hide passwords in properties file

You can use Jasypt to encrypt properties, so you could have your property like this:

db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)

Jasypt allows you to encrypt your properties using different algorithms, once you get the encrypted property you put inside the ENC(...). For instance, you can encrypt this way through Jasypt using the terminal:

encrypted-pwd$ java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar  org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="contactspassword" password=supersecretz algorithm=PBEWithMD5AndDES

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.45-b08

----ARGUMENTS-------------------

algorithm: PBEWithMD5AndDES
input: contactspassword
password: supersecretz

----OUTPUT----------------------

XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=

To easily configure it with Spring Boot you can use its starter jasypt-spring-boot-starter with group ID com.github.ulisesbocchio

Keep in mind, that you will need to start your application using the same password you used to encrypt the properties. So, you can start your app this way:

mvn -Djasypt.encryptor.password=supersecretz spring-boot:run

Or using the environment variable (thanks to spring boot relaxed binding):

export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run

You can check below link for more details:

https://www.ricston.com/blog/encrypting-properties-in-spring-boot-with-jasypt-spring-boot/

To use your encrypted properties in your app just use it as usual, use either method you like (Spring Boot wires the magic, anyway the property must be of course in the classpath):

Using @Value annotation

@Value("${db.password}")
private String password;

Or using Environment

@Autowired
private Environment environment;

public void doSomething(Environment env) {
System.out.println(env.getProperty("db.password"));
}

Update: for production environment, to avoid exposing the password in the command line, since you can query the processes with ps, previous commands with history, etc etc. You could:

  • Create a script like this: touch setEnv.sh
  • Edit setEnv.sh to export the JASYPT_ENCRYPTOR_PASSWORD variable

    #!/bin/bash

    export JASYPT_ENCRYPTOR_PASSWORD=supersecretz

  • Execute the file with . setEnv.sh
  • Run the app in background with mvn spring-boot:run &
  • Delete the file setEnv.sh
  • Unset the previous environment variable with: unset JASYPT_ENCRYPTOR_PASSWORD

Proper way of Securing Database credentials from a property file

You can use Jasypt, that'll allow you to store them in properties file but in encrypted form.

Although they are stored encrypted you could probably gain access to them if you mess up with RAM (because connection string is gonna be stored in RAM at some point). More secure way of protecting yourself is using Roles, Procedures and Views in the Database.

For example: Don't allow that user to create new tables, select what he wants, allow him to retrieve just some view, if you wanna check login credentials do that using procedure...

And finally, the safest option is to use server and go through server for everything.

Encrypt a password in a preferences/properties file - Java

It seems like you want to later decrypt and use that passwort to authenticate to the server. This means you can't hash it - hashing is good if you want the user to enter the password and then check if it is correct, but you cannot decrypt a hashed password to present it to the server.

Since your application will need to be able to decrypt the password to use it, an attacker that gains access to the configuration file will be able to decrypt the password the same way your application does it. No matter what you do, you can only make it more annoying to get the password (i.e. obfuscation/security by obscurity).

Steps you can take (program names that take that approach in braces):

  • Encrypt it in some proprietary way. It doesn't need to be secure, because no matter what you do, it won't. If someone bothers to find out how you did it, they can write a tool that will show the password. There is nothing you can do about that. You are only protecting against casual reading, and even a simple XOR is good enough for that. (Miranda)
  • Encrypt it using some proper encryption (again, don't worry too much about it, you're only using it because it is easier than doing it yourself) using a static key (anyone who gets the key will be able to decrypt it).
  • Encrypt it using some proper encryption and a random key and store the key next to the password. (Firefox)
  • Encrypt it using some proper encryption using a key derived from some data that change across systems (e.g. the user or system SID on Windows). This has the advantage that if someone steals the config (and nothing else) and later tries to decrypt it, he can't. This has the disadvantage that copying a config file to another installation will break the password, so you need to handle that case.
  • Not encrypt it to avoid giving a false kind of security. (Pidgin)
  • Storing the password in some kind of OS-provided wallet/credential manager (Windows credential manager, Gnome keyring, KDE wallet)

how to create and use encrypted Property files in Java?

You can use the javax.crypto.Cipher[Input|Output]Stream for reading/writing your data; however, you will have to enforce the write-once functionality in your code... maybe be comparing the data with a SHA hash or something to ensure that it has not been changed.

I have run across opensource and commercial license managers for Java... you may want to search around so as not to reinvent the wheel.

Also, you will probably want to look into obfuscation tools at least for your sensitive API if you want to keep users from decompiling it.

Hope this helps.



Related Topics



Leave a reply



Submit