bahuma20
bahuma20

Reputation: 23

Can't save Jasypt encrypted password to .properties file

I'm trying to store some strings in a .properties file. Now i want to encrypt those strings with Jasypt. But when I try to save this to the .properties file it is missing the surrounding "ENC()". When i try to insert this manually, the string is stored in clear text. Why?

StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("123456789");
Properties prop = new EncryptableProperties(encryptor);
prop.setProperty("key", "ENC(" + encryptor.encrypt("value") + ")");
prop.store(new FileOutputStream(System.getProperty("user.home") + "/.application-name/config.properties"), "Test");

Upvotes: 0

Views: 1713

Answers (1)

Stephen Hartley
Stephen Hartley

Reputation: 965

Looking at the JDK source code explains what's happening here. The cause is the class hierarchy involved; org.jasypt.properties.EncryptableProperties extends java.util.Properties which in turn extends java.util.Hashtable.

So when prop.store() is called, the method from java.util.Properties is invoked:

public void store(OutputStream out, String comments)
    throws IOException
{
    store0(new BufferedWriter(new OutputStreamWriter(out, "8859_1")),
           comments,
           true);
}

private void store0(BufferedWriter bw, String comments, boolean escUnicode)
    throws IOException
{
    if (comments != null) {
        writeComments(bw, comments);
    }
    bw.write("#" + new Date().toString());
    bw.newLine();
    synchronized (this) {
        for (Enumeration e = keys(); e.hasMoreElements();) {
            String key = (String)e.nextElement();
            String val = (String)get(key);
            key = saveConvert(key, true, escUnicode);
            /* No need to escape embedded and trailing spaces for value, hence
             * pass false to flag.
             */
            val = saveConvert(val, false, escUnicode);
            bw.write(key + "=" + val);
            bw.newLine();
        }
    }
    bw.flush();
}

The interesting line is

String val = (String)get(key);

EncryptableProperties defines a

public Object get(Object key)

method, overriding that of java.util.Hashtable - see the Jasypt API docs for EncryptableProperties. Hence the method below is invoked, which as you can see by reading the decode method, will perform the decryption, which in your case is not what you want!

public synchronized Object get(final Object key) {
    final Object value = super.get(key);
    final String valueStr = 
            (value instanceof String) ? (String)value : null;
    return decode(valueStr);
}


private synchronized String decode(final String encodedValue) {

    if (!PropertyValueEncryptionUtils.isEncryptedValue(encodedValue)) {
        return encodedValue;
    }
    if (this.stringEncryptor != null) {
        return PropertyValueEncryptionUtils.decrypt(encodedValue, this.stringEncryptor);

    }
    if (this.textEncryptor != null) {
        return PropertyValueEncryptionUtils.decrypt(encodedValue, this.textEncryptor);
    }

    /*
     * If neither a StringEncryptor nor a TextEncryptor can be retrieved
     * from the registry, this means that this EncryptableProperties
     * object has been serialized and then deserialized in a different
     * classloader and virtual machine, which is an unsupported behaviour. 
     */
    throw new EncryptionOperationNotPossibleException(
            "Neither a string encryptor nor a text encryptor exist " +
            "for this instance of EncryptableProperties. This is usually " +
            "caused by the instance having been serialized and then " +
            "de-serialized in a different classloader or virtual machine, " +
            "which is an unsupported behaviour (as encryptors cannot be " +
            "serialized themselves)");

}

To avoid this, don't use EncryptableProperties to store your properties, just using java.util.Properties will do. Simply replace

Properties prop = new EncryptableProperties(encryptor);

with

Properties prop = new Properties();

and the encrypted values will be stored in the properties file.

Upvotes: 1

Related Questions