Как использовать зашифрованный пароль в апачском BasicDataSource?

В настоящее время я сохраняю пароль [незашифрованным] в файле свойств. Этот пароль помещается, как находится в конфигурации xml использование муравья.
[Конфигурация xml для источника данных, она создает объект dbcp. BasicDataSource]

Теперь, это возможный, что после целевого объекта Ant пароль копируется в зашифрованном виде. Услышанный Jasypt может сделать это! До настоящего времени я не попробовал это. Но, проблема не заканчивается здесь. BasicDataSource не принимают зашифрованный пароль. Есть ли любая замена для BasicDatasource.

К вашему сведению: Я использую Spring, если это имеет значение.

14
задан Rakesh Juyal 6 August 2010 в 11:01
поделиться

4 ответа

Следующая ссылка jasypt объясняет, как файл свойств, содержащий зашифрованное содержимое, может быть прочитан из вашего приложения:

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

Для создания файла свойств из ANT я предлагаю использовать задачу groovy следующим образом:

<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>
3
ответ дан 1 December 2019 в 09:59
поделиться

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

Надеюсь, это поможет.

EDIT Если вы используете Jasypt, вам не нужно определять никаких PropertiesPersister. Из документации Jasypt:

Jasypt предоставляет реализацию этих связанных с конфигурацией классов Spring, которые могут читать файлы .properties с зашифрованными значениями (как те, которыми управляет класс EncryptableProperties) и обрабатывать их прозрачно для остальных бобов приложения Spring.

С помощью этого вы можете определить 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>

Таким образом, вы можете поместить пароль для расшифровки скрытого свойства в переменную окружения при запуске приложения и снять его позже.

17
ответ дан 1 December 2019 в 09:59
поделиться

Расширьте BasicDataSource, переопределите методы setPassword и setUserName. Расшифруйте значения в этих методах и передайте их методам суперкласса.

2
ответ дан 1 December 2019 в 09:59
поделиться

Не совсем верно в данном случае из BasicDataSource .

Если вы читаете javadocs для BasicDataSource , setPassword () не действует после инициализации пула. Пул инициализируется при первом вызове одного из следующих методов: getConnection , setLogwriter , setLoginTimeout , getLoginTimeout , getLogWriter .

Ссылка: http://www.docjar.com/html/api/org/apache/commons/dbcp/BasicDataSource.java.html

Все эти методы вызывают createDataSource () в конце концов.

Итак, ваш новый класс BasicDataSource должен только переопределить метод createDataSource () Примерно так:

public class NewBasicDataSource extends BasicDataSource {

    protected synchronized DataSource createDataSource() throws SQLException {
        String decryptedPassword = decryptPassword( super.getPassword() );
        super.setPassword( decryptedPassword );
        return super.createDataSource();
    }

    private String decryptPassword( String password ) {
        return //logic to decrypt current password
    }
}
3
ответ дан 1 December 2019 в 09:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: