Spring Boot如何在属性文件中隐藏密码

use*_*582 50 java spring spring-boot

Spring Boot使用属性文件,并且至少在默认情况下,密码是纯文本.有可能以某种方式隐藏/解密这些?

Fed*_*zza 63

您可以使用Jasypt加密属性,因此您可以拥有以下属性:

db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)
Run Code Online (Sandbox Code Playgroud)

Jasypt允许您使用不同的算法加密您的属性,一旦获得放入的加密属性ENC(...).例如,您可以使用终端通过Jasypt以这种方式加密:

encrypted-pwd$ java -cp ~/.m2/repository/org/jasypt/jasypt/1.9.2/jasypt-1.9.2.jar  org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="contactspassword" password=supersecretz algorithm=PBEWithMD5AndDES

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 24.45-b08



----ARGUMENTS-------------------

algorithm: PBEWithMD5AndDES
input: contactspassword
password: supersecretz



----OUTPUT----------------------

XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=
Run Code Online (Sandbox Code Playgroud)

要使用Spring Boot轻松配置它,您可以将其启动器jasypt-spring-boot-starter与组ID一起使用com.github.ulisesbocchio

请记住,您需要使用用于加密属性的相同密码来启动应用程序.所以,你可以这样开始你的应用程序:

mvn -Djasypt.encryptor.password=supersecretz spring-boot:run
Run Code Online (Sandbox Code Playgroud)

您可以查看以下链接了解更多详情:

https://www.ricston.com/blog/encrypting-properties-in-spring-boot-with-jasypt-spring-boot/

要在你的应用程序中使用加密属性,只需像往常一样使用它,使用你喜欢的任何一种方法(Spring Boot连接魔法,无论如何属性必须在类路径中):

使用@Value注释

export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run
Run Code Online (Sandbox Code Playgroud)

或使用 Environment

@Value("${db.password}")
private String password;
Run Code Online (Sandbox Code Playgroud)

  • 您能否请使用gradle @Frerica Piazza详细解释 (2认同)
  • @FedericoPiazza 不是 `mvn -Djasypt.encryptor.password=supersecretz spring-boot:run` 会出现在 `ps` 输出中,从而暴露密码吗? (2认同)

J-A*_*lex 14

对于已经提出的解决方案,我可以添加一个选项来配置外部,Secrets Manager例如Vault

  1. 配置 Vault 服务器vault server -dev仅适用于 DEV,不适用于 PROD
  2. 写秘密 vault write secret/somename key1=value1 key2=value2
  3. 验证秘密 vault read secret/somename

将以下依赖项添加到您的 SpringBoot 项目中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

添加 Vault 配置属性:

spring.cloud.vault.host=localhost
spring.cloud.vault.port=8200
spring.cloud.vault.scheme=http
spring.cloud.vault.authentication=token
spring.cloud.vault.token=${VAULT_TOKEN}
Run Code Online (Sandbox Code Playgroud)

VAULT_TOKEN作为环境变量传递。

请参阅此处的文档

有一个Spring Vault项目,它也可用于访问、存储和撤销机密。

依赖:

<dependency>
    <groupId>org.springframework.vault</groupId>
    <artifactId>spring-vault-core</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

配置 Vault 模板:

@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {

  @Override
  public VaultEndpoint vaultEndpoint() {
    return new VaultEndpoint();
  }

  @Override
  public ClientAuthentication clientAuthentication() {
    return new TokenAuthentication("…");
  }
}
Run Code Online (Sandbox Code Playgroud)

注入并使用 VaultTemplate:

public class Example {

  @Autowired
  private VaultOperations operations;

  public void writeSecrets(String userId, String password) {
      Map<String, String> data = new HashMap<String, String>();
      data.put("password", password);
      operations.write(userId, data);
  }

  public Person readSecrets(String userId) {
      VaultResponseSupport<Person> response = operations.read(userId, Person.class);
      return response.getBody();
  }
}
Run Code Online (Sandbox Code Playgroud)

使用保险柜PropertySource

@VaultPropertySource(value = "aws/creds/s3",
  propertyNamePrefix = "aws."
  renewal = Renewal.RENEW)
public class Config {

}
Run Code Online (Sandbox Code Playgroud)

用法示例:

public class S3Client {

  // inject the actual values
  @Value("${aws.access_key}")
  private String awsAccessKey;
  @Value("${aws.secret_key}")
  private String awsSecretKey;

  public InputStream getFileFromS3(String filenname) {
    // …
  }
}
Run Code Online (Sandbox Code Playgroud)

  • -1 因为这并没有解释“主”密钥 (VAULT_TOKEN) 是如何保护的。VAULT_TOKEN 环境变量从何而来?它是如何保障的?在不保护该密钥的情况下,攻击者可以使用它来使用 Spring Boot jar 中打包的代码从保险库中检索机密。 (4认同)

cod*_*ode 11

Spring Cloud Config Server将允许此类行为.使用JCE,您可以在服务器上设置密钥并使用它来加密应用程序属性.

http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html


San*_*wat 11

如果要隐藏密码,那么最简单的解决方案是在文件中或直接在代码中使用环境变量application.properties.

application.properties:

mypassword=${password}
Run Code Online (Sandbox Code Playgroud)

然后在您的配置类中:

@Autowired
private Environment environment;

[...]//Inside a method
System.out.println(environment.getProperty("mypassword"));
Run Code Online (Sandbox Code Playgroud)

在你的configuration班上:

@Value("${password}")
private String herokuPath;

[...]//Inside a method
System.out.println(herokuPath);
Run Code Online (Sandbox Code Playgroud)

注意:您可能必须在设置环境变量后重新启动.对于Windows:

在Windows中

有关详细信息,请参阅此文档.

  • 我不认为在环境变量中设置主密码是个好主意.密码现在暴露得比必要的更多.如Federico所示,为它提供一个初创公司比在环境中设置它更少曝光和更"安全". (18认同)