Search code examples
springhibernatedatasourceapache-commons-dbcppassword-encryption

Using encoded password for the datasource used in spring applicationContext.xml


I want to keep encoded password in my below mentioned springApplicationContext.xml

Is there any way to achieve this?

presently I have configured all properties using property-placeholder as shown below but the raw password is still open in my 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>

but actual values are present in my database.properties

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

I want something like below:

springApplicationContext.xml (same as above)

<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>

But password property value should be in encripted format in my database.properties

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

and my dataSource internally decrypt the password before making new DB connection.

Highly appreciate for any help/suggestion in this.


Solution

  • Its might be funny that I am answering to my own question. but still I just wanted to tell my solution, others who might have faced same kind of issue..

    for simplicity I have used BASE64Encoder & BASE64Decoder. later I will modify my code to use a secure/better encryption/decryption algorithm.

    I have encoded my database password(ex: root for my case) by using the below code:

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

    and placed the encoded password in my database.properties file like below:

    before

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

    after

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

    Now I have written a wrapper class for org.apache.commons.dbcp.BasicDataSource and overridden setPassword() method:

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

    This way I am decoding(BASE64Decoder) the encoded password provided in database.properties

    and also modified the class attribute of my dataSource bean mentioned in springApplicationContext.xml file.

    <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>
    

    Thanks.