如何在apache BasicDataSource中使用加密密码?

2022-09-03 18:33:11

目前,我将密码[未加密]保存在属性文件中。
[ 配置 xml 用于数据源,它正在创建 dbcp 的对象。基本数据源 ]

现在,在蚂蚁目标之后,密码是否有可能以加密形式复制。听说Jasypt可以做到这一点!到目前为止,我还没有尝试过这个。但是,问题并不止于此。基本数据源不接受加密密码。有没有 BasicDatasource 的替代品。

仅供参考:如果这很重要的话,我正在使用Spring。


答案 1

使用Spring有一个更好的方法:使用PropertyPlaceholderConfigurer类。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:com/foo/jdbc.properties</value>
    </property>
    <property name="propertiesPersister">
        <bean class="com.mycompany.MyPropertyPersister" />
    </property>        
</bean>

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

当您在属性占位符中指定 PropertiesPersister 的子类时,Spring 将加载 并使用该类解密文件。也许是这样的:jdbc.properties

public class MyPropertyPersister extends DefaultPropertiesPersister
{
    // ... initializing stuff...

    public void load(Properties props, InputStream is) throws IOException
    {
        Cipher decrypter = getCipher();
        InputStream cis = new CipherInputStream(is, decrypter);
        super.load(props, cis);
    }

    public void load(Properties props, Reader reader) throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IOUtils.copy(reader, baos);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

        Cipher decrypter = getCipher();
        InputStream cis = new CipherInputStream(bais, decrypter);

        InputStreamReader realReader = new InputStreamReader(cis);
        super.load(props, realReader);
    }

    public void loadFromXml(Properties props, InputStream is) throws IOException
    {
        Cipher decrypter = getCipher();
        InputStream cis = new CipherInputStream(is, decrypter);
        super.loadFromXml(props, cis);
    }

    private Cipher getCipher()
    {
         // return a Cipher to read the encrypted properties file
         ...
    }
    ...
}

希望它有帮助。

编辑如果使用 Jasypt,则无需定义任何 .来自 Jasypt 文档PropertiesPersister

Jasypt提供了这些与配置相关的Spring类的实现,它可以读取具有加密值的.properties文件(如由CrypticableProperties类管理的文件),并对Spring应用程序bean的其余部分透明地处理它们。

有了这个,你可以像这样定义jdbc.properties

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

而Spring配置可能是这样的

<bean class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
   <constructor-arg>
     <bean class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
       <property name="config">
         <bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
           <property name="algorithm" value="PBEWithMD5AndDES" />
           <property name="passwordEnvName" value="APP_ENCRYPTION_PASSWORD" />
         </bean>
       </property>
     </bean>
   </constructor-arg>
   <property name="locations">
     <list>
       <value>/WEB-INF/classes/jdbc.properties</value>
     </list>
   </property>   
</bean>

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

这样,您可以在启动应用程序时将用于解密隐藏属性的密码放在环境变量中,并在以后取消设置它。


答案 2

以下 jasypt 链接说明了如何从应用程序中读取包含加密内容的属性文件:

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

要从ANT内部创建属性文件,我的建议是使用时髦的任务,如下所示:

<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>

<groovy>
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor

def encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("secret"); 

def f = new File("config.properties")
f.println "datasource.driver=com.mysql.jdbc.Driver"
f.println "datasource.url=jdbc:mysql://localhost/reportsdb"
f.println "datasource.username=reportsUser"
f.println "datasource.password=ENC("+encryptor.encrypt("dbpassword")+")"    

</groovy>

推荐