ホームページ  >  記事  >  Java  >  Springboot が構成ファイル内の平文パスワードの暗号化を実装する方法

Springboot が構成ファイル内の平文パスワードの暗号化を実装する方法

WBOY
WBOY転載
2023-05-10 22:25:111453ブラウズ

表示例

この構成を見てみましょう:

spring:
  # 数据库链接配置
  datasource:
    url: jdbc:mysql://xx.xx.xx.xx:3306/database
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: "123456"

上記の構成の対応する値 spring.datasource.password123456, このような機密情報を構成ファイルに直接入れるのは不適切です。私たちがしなければならないことは、次のように、対応する値を暗号化された暗号文に変更することです:

spring:
  # 数据库链接配置
  datasource:
    url: jdbc:mysql://xx.xx.xx.xx:3306/database
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: "AES(DzANBAhBWXxZqAOsagIBCoaw8FV4gYRbid7G70UEM24=)"

この場合、たとえ構成ファイルは意図的に作成されており、誰かがそれを取得しても、実際のデータベースのパスワードがわからないため、プロジェクトに侵害のリスクをもたらすことはできません。

原則分析

この関数を実装するには、 Spring の関連する拡張ポイントと、対応するデータの暗号化と復号化の知識を理解する必要があります。まず、Spring のどの拡張ポイントを通過する必要があるかを見てみましょう。 ;

構成データをインターセプトしたい場合は、カスタム BeanFactoryPostProcessor を実装することで処理できます:

public class PropertySourcePostProcessor implements BeanFactoryPostProcessor {

  private ConfigurableEnvironment environment;

  public PropertySourcePostProcessor(ConfigurableEnvironment environment) {
    this.environment = environment;
  }

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    // 从ConfigurableEnvironment中取出所有的配置数据
    MutablePropertySources propertySources = this.environment.getPropertySources();
    propertySources.stream()
        // 过滤不需要包装的对象
        .filter(s -> !noWrapPropertySource(s))
        // 包装所有的PropertySource
        .map(s -> new EncryPropertySource(s))
        .collect(Collectors.toList())
        // 替换掉propertySources中的PropertySource
        .forEach(wrap -> propertySources.replace(wrap.getName(), wrap));
  }

  private boolean noWrapPropertySource(PropertySource propertySource) {
    return propertySource instanceof EncryPropertySource || StringUtils.equalsAny(propertySource.getClass().getName(), "org.springframework.core.env.PropertySource$StubPropertySource", "org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource");
  }
}

基本原理は次のように分析されます:

1. ConfigurableEnvironment ##PropertySource まで # をすべて取り出し、順番に走査します;

2. 満たさない

PropertySource をフィルターで除外しますPropertySource には多数のサブクラスがあり、そのすべてではないため、PropertySource インスタンスはすべてパッケージ化要件を満たしています;

3.

のパッケージ化レイヤーを作成します。要件を満たす PropertySource (実際には静的プロキシです);

4. 以前の

PropertySource インスタンスを、パッケージ化された PropertySource; # に置き換えます。 ##上記の一連の操作を通じて、

PropertySource

値を取得するときに、暗号文パスワードの復号化などのカスタム操作を実行できます。残りの問題は、暗号化と復号化です。暗号化には対称暗号化と非対称暗号化があり、この 2 つの暗号化方式の違いは、対称暗号化では暗号化と復号化に同じ鍵が必要であるのに対し、非対称暗号化では暗号化には公開鍵が、復号化には秘密鍵が必要であるという点です。

##対称暗号化と非対称暗号化を理解する 暗号化の違い、対称暗号化を使用している場合、暗号文とキーを同じ場所に置くことは避けなければなりません;

非対称暗号化

暗号文と秘密キーを同じ場所に;

ツールの紹介

次に、このニーズに特化した

jar

ツールを紹介します。それは

jasypt## です。 #、maven に移動して、ウェアハウス内で関連するパッケージを見つけます: <pre class="brush:xml;"> &lt;dependency&gt; &lt;groupId&gt;com.github.ulisesbocchio&lt;/groupId&gt; &lt;artifactId&gt;jasypt-spring-boot-starter&lt;/artifactId&gt; &lt;version&gt;3.0.5&lt;/version&gt; &lt;/dependency&gt;</pre> その実装原理は、実際には、BeanFactoryPostProcessor を ## にカスタマイズすることで、上で説明したものになります。 #ConfigurableEnvironment

PropertySourceインスタンスがインターセプトされてパッケージ化され、パッケージ化クラスの実装に対して復号化操作の層が実行され、暗号文パスワードの復号化が実現します。上記の依存関係をインポートした後、ツールは自動的に有効になり、対応する構成を変更できます。まず、ツールのいくつかの構成を作成します:

jasypt:
  encryptor:
    # 密钥
    password: ""
    property:
      # 密文前缀
      prefix: ""
      # 密文后缀
      suffix: ""
上記の構成では、jasypt. encryptor.password を設定する必要があります はい、これは暗号化キーと復号化キーです。デフォルトの暗号化アルゴリズムは PBEWITHHMACSHA512ANDAES_256

で、さらに

jasypt.encryptor.property.prefix

および

jasypt.encryptor.property.suffix は、それぞれ暗号文プレフィックスと暗号文サフィックスで、復号する必要がある暗号文をマークするために使用されます。構成されていない場合、デフォルトの暗号文プレフィックスは ENC( 、暗号文のサフィックスは ); デフォルトでは、暗号文は次のとおりです:

spring:
  datasource:
    password: "ENC(DzANBAhBWXxZqAOsagIBCoaw8FV4gYRbid7G70UEM24=)"
もう 1 つの注意点は、jasypt.encryptor.password## であることです。 # 暗号文と一緒に置くことはできません、プロジェクトのシステム プロパティ、コマンド ライン パラメータ、または環境変数を通じて渡すことができます; カスタム暗号化と復号化を実装します暗号化と復号化の場合

jasypt

が提供するメソッドはニーズを満たせません プロジェクトの要件については、暗号化と復号化を自分で実装することもできます: <pre class="brush:java;">@Bean(&quot;jasyptStringEncryptor&quot;) public StringEncryptor jasyptStringEncryptor(){ return new StringEncryptor() { @Override public String encrypt(String s) { // TODO 加密 return null; } @Override public String decrypt(String s) { // TODO 解密 return null; } }; }</pre>

BeanName

を ## に設定する必要があることに注意してください。 #jasyptStringEncryptor

がデフォルトで、それ以外の場合は有効になりません。この

BeanName を変更したい場合は、StringEncryptor# に対応する

BeanName

をカスタマイズすることもできます。 ## この構成パラメータを変更してインスタンスを作成します: <pre class="brush:yaml;">jasypt: encryptor: # 自定义StringEncryptor的BeanName bean: &quot;&quot;</pre>パスワード Text を生成する方法暗号文を生成する操作では、StringEncryptor インスタンスを呼び出して暗号化して生成する必要があります。次のコードを参照できます: <pre class="brush:java;">@Component public class StringEncryptorUtil{ @Autowired private StringEncryptor encryptor; public void encrypt(){ String result = encryptor.encrypt(&quot;123456&quot;); System.out.println(result); } }</pre>結局のところ、暗号化が必要な操作は、プロジェクトのライフサイクルで 1 回実行されるだけなので、単純にツール クラスを作成して呼び出すだけです。

以上がSpringboot が構成ファイル内の平文パスワードの暗号化を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。