12

xml spring config ファイルでパスワードを非表示/暗号化する方法はありますか? DataSource の「カスタム」サブクラスでそれが可能であると読みましたが、ソリューションはプレーンテキストと同じ構成ファイルにキーを保持しているため、少し役に立ちません。

これに KeyStore を使用する方法はありますか? たとえば、キーストアから値を読み取ります。

皆さんありがとう。

4

5 に答える 5

12

パスワードを隠す目的は何ですか?コンテナー (Tomcat、JBoss、または使用するもの) でデータソースを構成し、jndi を使用してデータソースをアプリケーションに挿入することをお勧めします。

<jee:jndi-lookup id="thedatasource"
                     jndi-name="java:comp/env/jdbc/thedatasource"
                     lookup-on-startup="false"
                     expected-type="javax.sql.DataSource"/>

この方法では、アプリケーションでパスワードを公開する必要はなく、サーブレット コンテナーでのみ公開する必要があります。

于 2010-11-16T16:44:21.350 に答える
11

はい、できます。データ ソース クラスの周りにラッパー Bean を作成する必要があります。以下は、私が以前に行った方法の例です。お役に立てれば!

<beans>
    <bean id="someDao" class="com.dao.SomeDAOImpl">
         <property name="datasource">
            <ref local="secureDataSource"/>
        </property>
    </bean>
    <bean id="secureDataSource" class="com.ds.SecureDataSource">
        <property name="driverClassName">
            <value><your driver></value>
        </property>
        <property name="url">
            <value><your url></value>
        </property>  
        <property name="username">
            <value><your user id></value>
        </property>
        <property name="password">
            <value><encrypted_pwd></value>
        </property> 
    </bean> 
</beans>

次に、SecureDataSource クラス内で、パスワードを復号化する必要があります。

import java.sql.Connection;
import java.sql.SQLException;


public class SecureDataSource extends DriverManagerDataSource{

    private String url;
    private String username;
    private String password;
    /**
     * @param url the url to set
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    protected Connection getConnectionFromDriverManager() throws SQLException {
        String decryptedPassword = null;
        //decrypt the password here
        return getConnectionFromDriverManager(url,username,decryptedPassword);
    }
}
于 2010-11-16T17:07:15.990 に答える
3

適切なオプションが提供されています。もう 1 つの明白な答えは、PropertyPlaceholderConfigurerを使用することです。

<context:property-placeholder
    system-properties-mode="OVERRIDE" 
    location="classpath:database.properties" />

<bean id="dataSource" class="com.whatever.datasource.you.Use">
    <property name="password" value="${database.password}" />
</bean> 

これで、パスワードをプロパティ ファイルのプロパティとして (SCM に保持したくない場合は展開中に作成することができます)、またはシステム プロパティとして (他の開発者の手の届かないところにあることを願っています) として保持できます。 )。

明確化: 展開中の作成はややあいまいです。おそらくサインアップ/ログインメカニズムと組み合わせて、エンドユーザーのマシンでプロパティファイルを動的に生成するインストーラーを作成する必要があると思います。


編集:あなたが誰から情報を隠しているのか、まだわかりません。2 つの理論:

a)あなたのソースコードにアクセスできる人
b) あなたの顧客

a) の場合は、私の道を進みます。他のすべての方法は、他の開発者がデバッガーでアプリケーションを起動しただけで簡単に破ることができます (そして突然、彼はデータソース オブジェクト内にいて、パスワードを確認します)。

b) の場合は、基本的にチャンスはありません。顧客は、デバッガー、エージェント、バイトコード操作、ロードタイム ウィービングなど、パスワードを取得する可能性がたくさんあります。たとえそれを行わなくても、パスワードを平文で取得するためにポート スニファーを接続する必要があります。文章。唯一の安全な方法は、顧客ごとにユーザー名/パスワードを用意することです (顧客のマシンにグローバル パスワードを保存しないでください)。

于 2010-11-16T17:15:51.770 に答える
0

最近同じ質問がありました。パスワードのハッシュ バージョンを .properties ファイルに保存したいと考えていました。前のオプションのおかげでうまくいきました。メソッドを拡張しDelegatingDataSourceてオーバーライドしました。getConnection([...])

public class UnhashingDataSource extends DelegatingDataSource {

    private static final Logger LOGGER = Logger.getLogger(UnhashingDataSource.class);
    private static final int HEX_RADIX = 16;
    private static final String DB_PASS = "a_sample_password";

    @Override
    public Connection getConnection() throws SQLException {
        DriverManagerDataSource dataSource = (DriverManagerDataSource) getTargetDataSource();
        return getConnection(dataSource.getUsername(), dataSource.getPassword());
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        try {
            DataSource datasource = getTargetDataSource();
            if (datasource == null) {
                throw new RuntimeException("targetDataSource is null");
            }
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.reset();
            md.update(DB_PASS.getBytes());
            if (password.equals(getHexString(md.digest()))) {
                return datasource.getConnection(username, DB_PASS);
            } else {
                throw new RuntimeException("Unable to connect to DB");
            }
        } catch (NoSuchAlgorithmException e) {
            LOGGER.error("Unknown algorithm");
        }
        return null;
    }

    private String getHexString(final byte[] messageDigest) {
        BigInteger bigInt = new BigInteger(1, messageDigest);
        return bigInt.toString(HEX_RADIX);
    }
}

次に、これを私の中でどのように使用したかを次に示しますapplicationContext.xml

# Using the unhashing datasource
<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="unhashingDataSource" />
    # ...
</bean>
<bean id="hashedDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${datasource.driverClassName}" />
    <property name="url" value="${datasource.url}" />
    <property name="username" value="${datasource.username}" />
    <property name="password" value="${datasource.hash}" />
</bean>
<bean id="unhashingDataSource"
    class="my.package.UnhashingDataSource">
    <property name="targetDataSource" ref="hashedDataSource" />
</bean>

プロパティ ( .propertiesdatasource.hashファイルから) は次のように保存されます。

datasource.hash = 2e54b0667ef542e3398c55a08a4e04e69b9769e8

単純なパスワードはバイトコードのままですが、.properties ファイルに直接ではありません。

于 2012-10-19T09:33:29.807 に答える
0

すべての投稿とクエリに感謝します。

このページを読んで、訪問者がパスワードを暗号化する技術的な方法を明確に理解できることを願っています。ここで追加したい重要なことの 1 つは、プロダクションを扱っている場合は、SHA-256 のような「セキュア ハッシュ アルゴリズム」とソルトを使用することをお勧めします。ソルトを使用した安全なハッシュ アルゴリズムを業界標準と見なすことができます。

于 2016-02-22T20:05:58.500 に答える