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

时间:2016-05-24 04:57:33

标签: java spring spring-boot

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

7 个答案:

答案 0 :(得分:48)

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

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

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=

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

一起使用

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

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

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

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;

或使用Environment

@Autowired
private Environment environment;

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

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

  • 创建如下脚本:touch setEnv.sh
  • 修改setEnv.sh以导出JASYPT_ENCRYPTOR_PASSWORD变量
      

    #!/斌/庆典

         

    导出JASYPT_ENCRYPTOR_PASSWORD = supersecretz

  • 使用. setEnv.sh
  • 执行文件
  • 使用mvn spring-boot:run &
  • 在后台运行应用
  • 删除文件setEnv.sh
  • 使用以下内容取消设置上一个环境变量:unset JASYPT_ENCRYPTOR_PASSWORD

答案 1 :(得分:12)

如果您想隐藏密码,那么最简单的解决方案是在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);

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

In Windows

有关详细信息,请参阅此Documentation

答案 2 :(得分:10)

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

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

答案 3 :(得分:1)

对于已经提出的解决方案,我可以添加一个选项来配置外部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>

添加保险柜配置属性:

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作为环境变量。

请参阅文档here.

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

依赖性:

<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();
  }
}

使用保险柜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) {
    // …
  }
}

答案 4 :(得分:0)

如果您在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

答案 5 :(得分:0)

我在Spring Boot App的application.properties中隐藏数据库密码的解决方案确实实现了here

场景:在运行时,已在全局Spring对象ConfigurableEnvironment中从application.properties开始读取并保存了一些虚假密码,在运行时将以编程方式用真实的DB-Password替换。 真正的密码将从另一个配置文件中读取,并保存在安全的项目外部位置。

别忘了:用以下方法调用Bean中的main class

@Autowired
private SchedUtilility utl;

答案 6 :(得分:0)

除了流行的K8,jasypt或Vault解决方案之外,还有Karmahostage。它使您能够:

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

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