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

Rak*_*yal 14 java apache ant encryption datasource

目前我将密码[未加密]保存在属性文件中.此密码使用ant放置在配置xml中.
[配置xml用于数据源,它正在创建dbcp.BasicDataSource的对象]

现在,是否有可能在ant目标之后以加密形式复制密码.听说Jasypt能做到这一点!直到现在我还没试过这个.但是,问题并没有在这里结束.BasicDataSource不接受加密密码.是否有BasicDatasource的替代品.

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

Ith*_*her 17

使用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>
Run Code Online (Sandbox Code Playgroud)

当您在属性占位符中指定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
         ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

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

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

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

 jdbc.driver=com.mysql.jdbc.Driver
 jdbc.url=jdbc:mysql://localhost/reportsdb
 jdbc.username=reportsUser
 jdbc.password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)
Run Code Online (Sandbox Code Playgroud)

并且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>
Run Code Online (Sandbox Code Playgroud)

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

  • 很有帮助.只是一个微不足道的修正,在属性文件中它是jdbc.driver但在bean定义中它是$ {jdbc.driverClassName}. (2认同)

Rak*_*yal 2

Copy通过扩展现有任务(负责文件复制)来创建新任务。通过扩展创建一个新类型FilterSet(负责过滤标记)。
请参阅此处的代码:- 如何为 ant 任务创建嵌套元素?

构建.xml

<target name="encrypted-copy" >
        <CopyEncrypted todir="dist/xyz/config" overwrite="true">
            <fileset dir="config"/>                 
            <encryptionAwareFilterSet>
                <filtersfile file="conf/properties/blah-blah.properties" />
            </encryptionAwareFilterSet>
        </CopyEncrypted>
    </target>
Run Code Online (Sandbox Code Playgroud)

等等等等.properties

property1=value1
property2=value2
PASSWORD=^&YUII%%&*(
USERNAME=rjuyal
CONNECTION_URL=...
someotherproperty=value
Run Code Online (Sandbox Code Playgroud)

配置文件

<bean id="dataSource"
        class="com.xyz.datasource.EncryptionAwareDataSource"
        destroy-method="close" autowire="byName">
        <property name="driverClassName">
            <value>com.ibm.db2.jcc.DB2Driver</value>
        </property>
        <property name="url">
            <value>@CONNECTION_URL@</value>
        </property>
        <property name="username">
            <value>@USERNAME@</value>
        </property>
        <property name="password">
            <value>@PASSWORD@</value>
        </property>
        <property name="poolPreparedStatements">
            <value>true</value>
        </property>
        <property name="maxActive">
            <value>10</value>
        </property>
        <property name="maxIdle">
            <value>10</value>
        </property>     
    </bean>
...
...
...
Run Code Online (Sandbox Code Playgroud)

执行目标后,将使用属性文件中的值复制 xml。密码将被加密。

这将处理加密的密码。 加密感知数据源

public class EncryptionAwareDataSource extends BasicDataSource{
    @Override
    public synchronized void setPassword(String password) {     
        super.setPassword(Encryptor.getDecryptedValue( password ));
    }
}
Run Code Online (Sandbox Code Playgroud)

仅此而已;)