23

我想在下面提到的 springApplicationContext.xml 中保留编码密码

有什么办法可以做到这一点?

目前我已经使用属性占位符配置了所有属性,如下所示,但原始密码仍然在我的 database.properties 中打开

springApplicationContext.xml

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property>
        <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property>
        <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property>
        <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>
</beans:bean>

但实际值存在于我的database.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=root

我想要下面的东西:

springApplicationContext.xml(同上)

<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property>
        <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property>
        <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property>
        <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>
</beans:bean>

但是密码属性值应该是我的加密格式database.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=3g6n72ef8x (using any encription method).

在建立新的数据库连接之前,我的数据源会在内部解密密码。

非常感谢您对此的任何帮助/建议。

4

5 回答 5

20

我回答自己的问题可能很有趣。但我仍然只想告诉我的解决方案,其他可能面临同样问题的人..

为简单起见,我使用了 BASE64Encoder 和 BASE64Decoder。稍后我将修改我的代码以使用安全/更好的加密/解密算法。

我已经使用以下代码对我的数据库密码(例如:我的案例的 root)进行了编码:

private String encode(String str) {
        BASE64Encoder encoder = new BASE64Encoder();
        str = new String(encoder.encodeBuffer(str.getBytes()));
        return str;
    }

并将编码的密码放在我的 database.properties 文件中,如下所示:

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=root

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/myDB
db.username=root
db.password=cm9vdA==  (Note: encoded 'root' by using BASE64Encoder)

现在我为 org.apache.commons.dbcp.BasicDataSource 编写了一个包装类并重写了 setPassword() 方法:

import java.io.IOException;
import org.apache.commons.dbcp.BasicDataSource;
import sun.misc.BASE64Decoder;

public class MyCustomBasicDataSource extends BasicDataSource{

    public CustomBasicDataSource() {
        super();
    }

    public synchronized void setPassword(String encodedPassword){
        this.password = decode(encodedPassword);
    }

    private String decode(String password) {
        BASE64Decoder decoder = new BASE64Decoder();
        String decodedPassword = null;
        try {
            decodedPassword = new String(decoder.decodeBuffer(password));
        } catch (IOException e) {
            e.printStackTrace();
        }       
        return decodedPassword;
    }
}

这样我正在解码(BASE64Decoder)database.properties中提供的编码密码

并且还修改了 springApplicationContext.xml 文件中提到的我的 dataSource bean 的类属性。

<beans:bean id="dataSource" class="edu.config.db.datasource.custom.MyCustomBasicDataSource" destroy-method="close">
    <beans:property name="driverClassName"><beans:value>${db.driverClassName}</beans:value></beans:property>
    <beans:property name="url"><beans:value>${db.url}</beans:value></beans:property>
    <beans:property name="username"><beans:value>${db.username}</beans:value></beans:property>
    <beans:property name="password"><beans:value>${db.password}</beans:value></beans:property>

谢谢。

于 2012-10-11T12:22:48.543 回答
10

创建自定义的 PropertyPlaceHolderConfigurer 扩展 Spring PropertyPlaceHolderConfigurer

public class PropertyPlaceholderConfigurer extends
        org.springframework.beans.factory.config.PropertyPlaceholderConfigurer {

    @Override
    protected String convertPropertyValue(final String originalValue) {
        if (originalValue.startwith("SomeText:")) {
            //Apply the decryption logic
            ...
        }
    }
}

您可以加密属性并附加SomeText:。使用此自定义 PropertyPlaceHolderConfigurer 加载属性

于 2012-10-11T12:27:09.883 回答
4

我想在这里看大图:为什么要加密属性文件中的值?未经授权的人可以访问您的属性文件的情况是什么?

处理存储生产凭证这一更大问题的常用技术是使凭证成为您环境的一部分,而不是源代码的一部分。这里有一些方法可以做到这一点:

  • 将属性文件(带有明文密码)放在生产环境中 Web 服务器的类路径中,这样对密码的访问由对生产机器的访问控制。
  • 将属性存储在 web.xml(带有参数名称的上下文参数)中,此文件也是您运行代码的环境的一部分,而不是随代码一起分发 - 对该文件的访问由对机器的访问控制。
  • 使用 JNDI 并在应用程序服务器中配置该资源。
于 2012-10-11T19:01:05.507 回答
3

创建一个实现接口的包装类,该Datasource接口将其方法调用委托给底层数据源,但在此之前解密密码。

于 2012-10-11T07:50:04.093 回答
0

如果您使用 tomcat 连接池作为数据源,这里是一个实现

http://www.jdev.it/encrypting-passwords-in-tomcat/

创建一个扩展 org.apache.tomcat.jdbc.pool.DataSourceFactory 的类并在 server.xml 中配置它

更新:

较新的方法是使用 Jasypt:http ://www.jasypt.org/encrypting-texts.html

于 2014-08-14T06:33:20.400 回答