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

SpringBoot 使用属性文件,至少在默认情况下,密码是纯文本的。有没有可能隐藏或解密这些信息?

175968 次浏览

SpringCloudConfig 服务器将允许此类行为。使用 JCE,您可以在服务器上设置一个密钥,并使用它来加密应用程序的属性。

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

更新: 我注意到人们对此投了反对票,所以我不得不说,虽然这不是一个理想的解决方案,但是在某些用例中,这是可行的,也是可以接受的。 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

而且,如果您的系统不是共享的,那么对于本地开发来说,这也是可以接受的。当然,更安全和可靠的方法在 回答我中由@J-Alex 解释。

Answer:

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

application.properties:

mypassword=${password}

然后在配置类中:

@Autowired
private Environment environment;


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

在你的 configuration课上:

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


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

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

In Windows

请参考此 文件了解更多信息。

您可以使用 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:

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=

要使用 SpringBoot 轻松地配置它,可以使用其启动器 Jasypt 弹簧启动器和组 ID com.github.ulisesbocchio

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

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

或者使用环境变量(感谢弹簧靴松弛绑定) :

export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run

你可浏览以下连结了解详情:

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

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

使用 @Value注释

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

Or using Environment

@Autowired
private Environment environment;


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

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

  • 创建如下脚本: touch setEnv.sh
  • Edit setEnv.sh to export the JASYPT_ENCRYPTOR_PASSWORD variable

    # !/bin/bash

    export JASYPT_ENCRYPTOR_PASSWORD=supersecretz

  • . setEnv.sh执行文件
  • Run the app in background with mvn spring-boot:run &
  • 删除文件 setEnv.sh
  • 取消之前的环境变量: unset JASYPT_ENCRYPTOR_PASSWORD

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

  1. 配置保险库服务器 vault server -dev(只适用于 DEV,而不适用于 PROD)
  2. Write secrets 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>

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

作为环境变量通过 VAULT_TOKEN考试。

请参考文档 给你。

有一个 弹簧跳马项目,也可以用于访问,存储和撤销秘密。

依赖性:

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

配置保险库模板:

@Configuration
class VaultConfiguration extends AbstractVaultConfiguration {


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


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

注入和使用 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:

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


}

用法例子:

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

如果您在 Spring Boot 环境 Kubernetes (K8S)或 OpenShift 中使用非常流行,那么在运行时存储和检索应用程序属性是有可能的。这种技术被称为 秘密。在 Kubernetes 或 OpenShift 的配置 yaml 文件中,为其声明变量和占位符,并在 K8S OpenShift 端声明与此占位符相对应的实际值。 有关实施细节,请参阅: K8S: https://kubernetes.io/docs/concepts/configuration/secret/ OpenShift: < a href = “ https://docs.OpenShift. com/container-Platform/3.11/dev _ guide/secret s.html”rel = “ nofollow norefrer”> https://docs.OpenShift.com/container-platform/3.11/dev_guide/secrets.html

我在 SpringBootApp 的 应用性能中隐藏 DB-Password 的解决方案实现了 给你

Scenario: some fake password already reading and saved from 应用性能 on start, in global Spring object ConfigurableEnvironment will be, in Run-Time replaced programmaticaly, by real DB-Password. 真正的密码将从另一个配置文件读取,保存在安全的项目外部位置。

不要忘记: 从 主课打电话给 Bean:

@Autowired
private SchedUtilility utl;

除了流行的 K8,jasypt 或者穹顶解决方案,还有 因果报应。它可以让你做:

@EncryptedValue("${application.secret}")
private String application;

它的工作方式与 jasypt 相同,但是加密发生在专用的 saas 解决方案上,并附加了更细粒度的 ACL 模型。