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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37404703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:17:30  来源:igfitidea点击:

Spring Boot how to hide passwords in properties file

javaspringspring-boot

提问by user1340582

Spring Boot uses the properties file, and at least by default, the passwords are in plain text. Is it possible to somehow hide/decrypt these?

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

采纳答案by Federico Piazza

You can use Jasyptto encrypt properties, so you could have your property like this:

您可以使用Jasypt来加密属性,因此您可以拥有这样的属性:

db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)

Jasypt allows you to encrypt your properties using different algorithms, once you get the encrypted property you put inside the ENC(...). For instance, you can encrypt this way through Jasypt using the terminal:

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=

To easily configure it with Spring Boot you can use its starter jasypt-spring-boot-starterwith group ID com.github.ulisesbocchio

要使用 Spring Boot 轻松配置它,您可以使用它的启动器jasypt-spring-boot-starter和组 IDcom.github.ulisesbocchio

Keep in mind, that you will need to start your application using the same passwordyou used to encrypt the properties. So, you can start your app this way:

请记住,您需要使用用于加密属性的相同密码来启动您的应用程序。因此,您可以通过以下方式启动您的应用:

mvn -Djasypt.encryptor.password=supersecretz spring-boot:run

Or using the environment variable (thanks to spring boot relaxed binding):

或者使用环境变量(感谢 spring boot 轻松绑定):

export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run

You can check below link for more details:

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

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

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

To use your encrypted properties in your app just use it as usual, use either method you like (Spring Boot wires the magic, anyway the property must be of course in the classpath):

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

Using @Valueannotation

使用@Value注解

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

Or using Environment

或者使用 Environment

@Autowired
private Environment environment;

public void doSomething(Environment env) {
    System.out.println(env.getProperty("db.password"));
}

Update: for production environment, to avoid exposing the password in the command line, since you can query the processes with ps, previous commands with history, etc etc. You could:

更新:对于生产环境,为了避免在命令行中暴露密码,因为您可以使用 查询进程ps,使用之前的命令history等等。您可以:

  • Create a script like this: touch setEnv.sh
  • Edit setEnv.shto export the JASYPT_ENCRYPTOR_PASSWORDvariable

    #!/bin/bash

    export JASYPT_ENCRYPTOR_PASSWORD=supersecretz

  • Execute the file with . setEnv.sh
  • Run the app in background with mvn spring-boot:run &
  • Delete the file setEnv.sh
  • Unset the previous environment variable with: unset JASYPT_ENCRYPTOR_PASSWORD
  • 创建一个这样的脚本: touch setEnv.sh
  • 编辑setEnv.sh以导出JASYPT_ENCRYPTOR_PASSWORD变量

    #!/bin/bash

    导出 JASYPT_ENCRYPTOR_PASSWORD=supersecretz

  • 执行文件 . setEnv.sh
  • 在后台运行应用程序 mvn spring-boot:run &
  • 删除文件 setEnv.sh
  • 使用以下命令取消设置先前的环境变量: unset JASYPT_ENCRYPTOR_PASSWORD

回答by code

Spring Cloud Config Server will allow this type of behavior. Using JCE you can setup a key on the server and use it to cipher the apps properties.

Spring Cloud Config Server 将允许这种类型的行为。使用 JCE,您可以在服务器上设置一个密钥并使用它来加密应用程序属性。

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

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

回答by Sanjay Rawat

UPDATE:I noticed folks down-voting this, so I have to say that although this is not an ideal solution, but this works and acceptable in some use-cases. Cloudfoundry uses Environment variables to inject credentials when a Service is binded to an application. More info https://docs.cloudfoundry.org/devguide/services/application-binding.html

更新:我注意到人们对此投反对票,所以我不得不说,虽然这不是一个理想的解决方案,但在某些用例中这是可行的并且可以接受的。当服务绑定到应用程序时,Cloudfoundry 使用环境变量来注入凭据。更多信息https://docs.cloudfoundry.org/devguide/services/application-binding.html

And also if your system is not shared, then for local development this is also acceptable. Of course, the more safe and secure way is explained in Answerby @J-Alex.

而且,如果您的系统不是共享的,那么对于本地开发,这也是可以接受的。当然,@J-Alex在Answer 中解释了更安全可靠的方式。

Answer:

回答:

If you want to hide your passwords then the easiest solution is to use Environment variablesin application.propertiesfile or directly in your code.

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

In application.properties:

application.properties

mypassword=${password}

Then in your configuration class:

然后在您的配置类中:

@Autowired
private Environment environment;

[...]//Inside a method
System.out.println(environment.getProperty("mypassword"));

In your configurationclass:

在你的configuration课堂上:

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

[...]//Inside a method
System.out.println(herokuPath);

Note:You might have to restart after setting the environment variable. For windows:

注意:您可能需要在设置环境变量后重新启动。对于窗户:

In Windows

在 Windows 中

Refer this Documentationfor more info.

有关更多信息,请参阅此文档

回答by J-Alex

To the already proposed solutions I can add an option to configure an external Secrets Managersuch as Vault.

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

  1. Configure Vault Server vault server -dev(Only for DEV and not for PROD)
  2. Write secrets vault write secret/somename key1=value1 key2=value2
  3. Verify secrets vault read secret/somename
  1. 配置 Vault 服务器vault server -dev仅适用于 DEV,不适用于 PROD
  2. 写秘密 vault write secret/somename key1=value1 key2=value2
  3. 验证秘密 vault read secret/somename

Add the following dependency to your SpringBoot project:

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

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>

Add Vault config properties:

添加 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}

Pass VAULT_TOKENas an environment variable.

VAULT_TOKEN作为环境变量传递。

Refer to the documentation here.

请参阅此处的文档

There is a Spring Vaultproject which is also can be used for accessing, storing and revoking secrets.

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

Dependency:

依赖:

<dependency>
    <groupId>org.springframework.vault</groupId>
    <artifactId>spring-vault-core</artifactId>
</dependency>

Configuring Vault Template:

配置 Vault 模板:

@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {

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

  @Override
  public ClientAuthentication clientAuthentication() {
    return new TokenAuthentication("…");
  }
}

Inject and use VaultTemplate:

注入并使用 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();
  }
}

Use Vault PropertySource:

使用保险柜PropertySource

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

}

Usage example:

用法示例:

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) {
    // …
  }
}

回答by stinger

In case you are using quite popular in Spring Boot environment Kubernetes (K8S) or OpenShift, there's a possibility to store and retrieve application properties on runtime. This technique called secrets. In your configuration yaml file for Kubernetes or OpenShift you declare variable and placeholder for it, and on K8S\OpenShift side declare actual value which corresponds to this placeholder. For implementation details, see: K8S: https://kubernetes.io/docs/concepts/configuration/secret/OpenShift: https://docs.openshift.com/container-platform/3.11/dev_guide/secrets.html

如果您在 Spring Boot 环境 Kubernetes (K8S) 或 OpenShift 中使用非常流行,则可以在运行时存储和检索应用程序属性。这种技术称为秘密。在 Kubernetes 或 OpenShift 的配置 yaml 文件中,您为其声明变量和占位符,并在 K8S\OpenShift 端声明与此占位符对应的实际值。实现细节参见:K8S:https://kubernetes.io/docs/concepts/configuration/secret/ OpenShift:https://docs.openshift.com/container-platform/3.11/dev_guide/secrets.html