この構成を見てみましょう:
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.password
は 123456
, このような機密情報を構成ファイルに直接入れるのは不適切です。私たちがしなければならないことは、次のように、対応する値を暗号化された暗号文に変更することです:
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 まで # をすべて取り出し、順番に走査します;
PropertySource をフィルターで除外します
PropertySource には多数のサブクラスがあり、そのすべてではないため、
PropertySource インスタンスはすべてパッケージ化要件を満たしています;
のパッケージ化レイヤーを作成します。要件を満たす PropertySource (実際には静的プロキシです);
PropertySource インスタンスを、パッケージ化された
PropertySource;
# に置き換えます。 ##上記の一連の操作を通じて、
値を取得するときに、暗号文パスワードの復号化などのカスタム操作を実行できます。残りの問題は、暗号化と復号化です。暗号化には対称暗号化と非対称暗号化があり、この 2 つの暗号化方式の違いは、対称暗号化では暗号化と復号化に同じ鍵が必要であるのに対し、非対称暗号化では暗号化には公開鍵が、復号化には秘密鍵が必要であるという点です。
非対称暗号化
暗号文と秘密キーを同じ場所に;ツールの紹介
jasypt## です。 #、maven
に移動して、ウェアハウス内で関連するパッケージを見つけます: <pre class="brush:xml;"> <dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency></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("jasyptStringEncryptor")
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 を変更したい場合は、
StringEncryptor# に対応する
をカスタマイズすることもできます。 ## この構成パラメータを変更してインスタンスを作成します: <pre class="brush:yaml;">jasypt:
encryptor:
# 自定义StringEncryptor的BeanName
bean: ""</pre>
パスワード Text を生成する方法暗号文を生成する操作では、
StringEncryptor
インスタンスを呼び出して暗号化して生成する必要があります。次のコードを参照できます: <pre class="brush:java;">@Component
public class StringEncryptorUtil{
@Autowired
private StringEncryptor encryptor;
public void encrypt(){
String result = encryptor.encrypt("123456");
System.out.println(result);
}
}</pre>
結局のところ、暗号化が必要な操作は、プロジェクトのライフサイクルで 1 回実行されるだけなので、単純にツール クラスを作成して呼び出すだけです。
以上がSpringboot が構成ファイル内の平文パスワードの暗号化を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。