it-swarm.com.de

Verwenden eines verschlüsselten Kennworts für die Datenquelle, die in spring applicationContext.xml verwendet wird

Ich möchte das verschlüsselte Passwort in meiner unten genannten springApplicationContext.xml behalten

Gibt es eine Möglichkeit, dies zu erreichen? 

derzeit habe ich alle Eigenschaften mit property-placeholderas konfiguriert, aber das rohe Passwort ist noch in meiner Datenbank.properties geöffnet

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>

aber tatsächliche Werte sind in meinem database.properties vorhanden

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

Ich möchte etwas wie unten:

springApplicationContext.xml (wie oben)

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

Der Kennworteigenschaftswert sollte jedoch in meinem database.properties in einem verschlüsselten Format vorliegen.

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

und meine dataSource entschlüsseln das Kennwort intern, bevor eine neue DB-Verbindung hergestellt wird.

Ich freue mich über jede Hilfe/Anregung.

21
Sandy

Es könnte komisch sein, dass ich auf meine eigene Frage antworte. Ich wollte aber trotzdem nur meine Lösung mitteilen, andere, die möglicherweise vor einem ähnlichen Problem standen.

zur Vereinfachung habe ich BASE64Encoder & BASE64Decoder verwendet. Später werde ich meinen Code ändern, um einen sicheren/besseren Verschlüsselungs-/Entschlüsselungsalgorithmus zu verwenden.

Ich habe mein Datenbankkennwort (ex: root für meinen Fall) mit dem folgenden Code verschlüsselt:

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

und das verschlüsselte Passwort wie folgt in meine Datei database.properties eingefügt:

vor

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

nach dem

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

Jetzt habe ich eine Wrapper-Klasse für die org.Apache.commons.dbcp.BasicDataSource Und die überschriebene setPassword () - Methode geschrieben:

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

Auf diese Weise decodiere (BASE64Decoder) das in der Datei database.properties angegebene verschlüsselte Kennwort

außerdem wurde das Klassenattribut meiner in der Datei springApplicationContext.xml genannten DataSource-Bean geändert.

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

Vielen Dank.

19
Sandy

Erstellen Sie einen angepassten PropertyPlaceHolderConfigurer, der den Spring PropertyPlaceHolderConfigurer erweitert.

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

Sie können die Eigenschaften verschlüsseln und SomeText anhängen:. Verwenden Sie diesen angepassten PropertyPlaceHolderConfigurer, um die Eigenschaften zu laden

9
Sujith

Ich möchte das größere Bild hier betrachten: Warum möchten Sie Werte in Ihrer Eigenschaftendatei verschlüsseln? In welchem ​​Szenario haben nicht autorisierte Personen Zugriff auf Ihre Eigenschaftendatei? 

Eine übliche Technik, um mit diesem größeren Problem des Speicherns von Produktionsanmeldeinformationen umzugehen, besteht darin, die Anmeldeinformationen zu einem Teil Ihrer Umgebung und nicht zu einem Teil Ihres Quellcodes zu machen. Hier sind einige Möglichkeiten, dies zu tun:

  • Wenn Sie die Eigenschaftendatei (mit Klartextkennwörtern) auf dem Klassenpfad des Webservers in der Produktion platzieren, wird der Zugriff auf dieses Kennwort durch den Zugriff auf die Produktionsmaschine gesteuert.
  • Speichern Sie die Eigenschaften in web.xml (context-param mit param-name). Diese Datei ist wiederum Teil der Umgebung, in der Sie Ihren Code ausführen und nicht mit Ihrem Code verteilt werden. Der Zugriff auf diese Datei wird durch den Zugriff auf den Computer gesteuert.
  • Verwenden Sie JNDI und konfigurieren Sie diese Ressource in Ihrem Anwendungsserver.
3
Jay

Erstellen Sie eine Wrapper-Klasse, die die Datasource-Schnittstelle implementiert, die ihre Methodenaufrufe an die zugrunde liegende Datenquelle delegiert, das Kennwort jedoch zuvor entschlüsselt.

3
Abhinav Sarkar

Wenn Sie einen Tomcat-Verbindungspool als Datenquelle verwenden, finden Sie hier eine Implementierung 

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

Erstellen Sie eine Klasse, die org.Apache.Tomcat.jdbc.pool.DataSourceFactory erweitert, und konfigurieren Sie sie in server.xml 

0
Sujith Nair