无法将Jasypt加密密码保存到.properties文件中

时间:2015-03-12 14:37:34

标签: java encryption jasypt

我试图在.properties文件中存储一些字符串。现在我想用Jasypt加密这些字符串。但是当我尝试将其保存到.properties文件时,它缺少周围的" ENC()"。当我尝试手动插入时,字符串以明文形式存储。为什么呢?

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");

1 个答案:

答案 0 :(得分:1)

查看JDK源代码解释了这里发生了什么。原因是涉及的类层次结构; org.jasypt.properties.EncryptableProperties扩展java.util.Properties,后者又扩展java.util.Hashtable

因此,当调用prop.store()时,将调用java.util.Properties中的方法:

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();
}

有趣的一行是

String val = (String)get(key);

EncryptableProperties定义了

public Object get(Object key)

方法,覆盖java.util.Hashtable - see the Jasypt API docs for EncryptableProperties的方法。因此,调用下面的方法,正如您通过阅读decode方法所看到的,将执行解密,在您的情况下,这不是您想要的!

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)");

}

为避免这种情况,请勿使用EncryptableProperties来存储您的媒体资源,只需使用java.util.Properties即可。只需更换

Properties prop = new EncryptableProperties(encryptor);

Properties prop = new Properties();

,加密值将存储在属性文件中。