How to Encrypt Decrypt a Password Stored in a Properties File with Java + Jasypt + Apache Commons Configuration

Introduction

[UPDATE: To help reader with a workable code-base, I’ve added a maven based project at GitHub. Checkout the code here]

Often password information is kept in a properties file for some Java based application. Password often needs to be changed so having them in properties file is a convenient way to update password without changing and recompiling source java code. However this convenience puts the password exposed in a text based properties file. For example Java application may store a database connection password in a properties file. This tutorial will show how to encrypt a password text stored in a properties file and retrieve the password later through a decryption process. JSypt will be used for encryption and decryption task. Apache Commons Configuration project will be used to easily manipulate properties file.

Sandbox Environment

  • OS: Windows 7 32 bit
  • IDE: Eclipse Juno
  • Libraries
    • Jasypt 1.9.0
    • Apache Commons Configuration 1.9

Steps

This is a simple project with only two java class and one properties file. If you run the tester it will encrypt a password and then decrypt it back. Go through the code and code comments to follow and understand how Jasypt is working.

The Encryptor & Decryptor Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.sortedset.jasyptblog;
 
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
 
public class EncryptDecrypt {
    private final String propertyFileName;
    private final String propertyKey;
    private final String isPropertyKeyEncrypted;
 
    final String decryptedUserPassword;
 
    /**
     * The constructor does most of the work.
     * It initializes all final variables and invoke two methods
     * for encryption and decryption job. After successful job
     * the constructor puts the decrypted password in variable
     * to be retrieved by calling class.
     * 
     * 
     * @param pPropertyFileName /Name of the properties file that contains the password
     * @param pUserPasswordKey  /Left hand side of the password property as key. 
     * @param pIsPasswordEncryptedKey   /Key in the properties file that will tell us if the password is already encrypted or not
     * 
     * @throws Exception
     */
    public EncryptDecrypt(String pPropertyFileName,String pUserPasswordKey, String pIsPasswordEncryptedKey) throws Exception {
        this.propertyFileName = pPropertyFileName;
        this.propertyKey = pUserPasswordKey;
        this.isPropertyKeyEncrypted = pIsPasswordEncryptedKey;
        try {
            encryptPropertyValue();
        } catch (ConfigurationException e) {
            throw new Exception("Problem encountered during encryption process",e);
        }
        decryptedUserPassword = decryptPropertyValue();
 
    }
 
    /**
     * The method that encrypt password in the properties file. 
     * This method will first check if the password is already encrypted or not. 
     * If not then only it will encrypt the password.
     * 
     * @throws ConfigurationException
     */
    private void encryptPropertyValue() throws ConfigurationException {
        System.out.println("Starting encryption operation");
        System.out.println("Start reading properties file");
 
        //Apache Commons Configuration 
        PropertiesConfiguration config = new PropertiesConfiguration(propertyFileName);
 
        //Retrieve boolean properties value to see if password is already encrypted or not
        String isEncrypted = config.getString(isPropertyKeyEncrypted);
 
        //Check if password is encrypted?
        if(isEncrypted.equals("false")){
            String tmpPwd = config.getString(propertyKey);
            //System.out.println(tmpPwd); 
            //Encrypt
            StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
            // This is a required password for Jasypt. You will have to use the same password to
            // retrieve decrypted password later. T
            // This password is not the password we are trying to encrypt taken from properties file.
            encryptor.setPassword("jasypt");
            String encryptedPassword = encryptor.encrypt(tmpPwd);
            System.out.println("Encryption done and encrypted password is : " + encryptedPassword ); 
 
            // Overwrite password with encrypted password in the properties file using Apache Commons Cinfiguration library
            config.setProperty(propertyKey, encryptedPassword);
            // Set the boolean flag to true to indicate future encryption operation that password is already encrypted
            config.setProperty(isPropertyKeyEncrypted,"true");
            // Save the properties file
            config.save();
        }else{
             System.out.println("User password is already encrypted.\n ");
        }
    }
 
    private String decryptPropertyValue() throws ConfigurationException {
         System.out.println("Starting decryption");
        PropertiesConfiguration config = new PropertiesConfiguration(propertyFileName);
        String encryptedPropertyValue = config.getString(propertyKey);
        //System.out.println(encryptedPropertyValue); 
 
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword("jasypt");
        String decryptedPropertyValue = encryptor.decrypt(encryptedPropertyValue);
        //System.out.println(decryptedPropertyValue); 
 
        return decryptedPropertyValue;
    }
}

Tester

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.sortedset.jasyptblog;
 
import junit.framework.Assert;
 
import org.junit.Test;
 
public class EncryptDecryptTest {
    public EncryptDecryptTest() {
    }
 
    @Test
    public void encryptDecryptTest() throws Exception {
        //Name of the properties file that needs encryption
        String propertyFileName = "application.properties";
        //Key portion of the properties the left hand side
        String userPwdKey = "database.user.password" ;
        //Key in the properties file that will tell us if the password is already encrypted or not
        String isPwdEcnryptedKey = "is.database.user.password.encrypted";
 
        //Invoke the constrsuctor
        EncryptDecrypt app = new EncryptDecrypt(propertyFileName,userPwdKey,isPwdEcnryptedKey);
 
        //Retrieve the decrypted password
        String result = app.decryptedUserPassword;
        Assert.assertTrue("Decrypted password should be \"myPassWord\"", result.equalsIgnoreCase("myPassWord"));
    }
 
}

The properties file

1
2
3
database.user.name=clouduser
database.user.password=mydbpassword
is.database.user.password.encrypted=false

The properties file after encryption

1
2
3
database.user.name=clouduser
database.user.password=Gsi3ZNTtven+WjExGA1Q3UD1brweHOqf
is.database.user.password.encrypted=true

Resources

11 Comments

  1. Cijo Kundukulangara April 4, 2013 Reply
    • Mitch May 2, 2013 Reply
      • Paul Eden January 31, 2014 Reply
        • iqbalyusuf March 2, 2014 Reply
          • Nick February 13, 2015
  2. dbsecu May 4, 2013 Reply
  3. doyle July 4, 2013 Reply
  4. luniaadarshaA May 4, 2015 Reply
  5. Savani August 15, 2016 Reply
  6. Bahamut November 10, 2016 Reply
  7. Tom April 19, 2017 Reply

Add a Comment

Your email address will not be published. Required fields are marked *