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


81

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

Answers:


86

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

    #!/ bin / bash

    导出JASYPT_ENCRYPTOR_PASSWORD = supersecretz

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

2
能否请你解释更多的gradle使用广场@Frerica细节
TESTUSER

关于与Maven一起使用尚不清楚。您传递了一些财产,还有什么呢?属性文件在哪里?如何在代码中获得此值?
gstackoverflow

1
@FedericoPiazza不会mvn -Djasypt.encryptor.password=supersecretz spring-boot:run显示在ps输出中,公开密码吗?
Srki Rakic

1
@SrkiRakic是的,当然。这仅用于开发,如果要用于生产,则应使用环境变量。弹簧靴可让您使用JASYPT_ENCRYPTOR_PASSWORD
Federico Piazza

1
哈哈,它如何进入环境变量?可能来自另一个文件,例如服务定义:D在涉及密码派生时,jasypt也已过时,因此请确保使用完全随机的32个字符的密码
RomanPlášil19年

14

更新:我注意到人们对此表示反对,所以我不得不说,尽管这不是理想的解决方案,但是在某些用例中,它是可行的并且可以接受的。当服务绑定到应用程序时,Cloudfoundry使用环境变量来注入凭据。更多信息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);

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

在Windows中

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


25
我认为在环境vars中设置主密码不是一个好主意。现在,密码暴露得比必要的多。与将其设置在环境中相比,像Federico所示为它提供启动服务更容易暴露,也更“安全”。
Jaavaaan

是的,如果您使用共享计算机,则不会。但是,如果您是计算机的唯一管理员,则没有其他用户可以看到环境变量。我回答了隐藏部分和较容易的部分。但是,是的,我同意费德里科的建议方法更好。
Sanjay Rawat



11

在已经提出的解决方案中,我可以添加一个选项来配置外部文件,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作为环境变量传递。

请参阅此处的文档

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

此解决方案+1。使用Vault / etcd(或其他任何系统)之类的方法是可行的。diogomonica.com/2017/03/27/...
本书的宙斯

3
-1,因为这不能说明如何保护“主”密钥(VAULT_TOKEN)。VAULT_TOKEN环境变量来自何处?如何保证安全?在不保护该密钥的情况下,攻击者可以使用Spring Boot jar中打包的代码,使用它来从Vault中检索秘密。
Corporatedrone

确保产品安全也是主要问题。因此,必须在这里说。Dev / QA环境指南,如果可以的话。
sofs1

密码很多时可以使用。它可以使用一个密码进行连接,但是有趣的是可以将Vault密码放入环境中,因此您不必将另一个密码放入相同的环境中。
Lee Meador19年

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


0

我在Spring Boot App的application.properties中隐藏DB-Password的解决方案已在此处实现

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

别忘了:使用以下命令从主类调用Bean

@Autowired
private SchedUtilility utl;

0

除了流行的K8,jasypt或Vault解决方案之外,还有Karmahostage。它使您可以执行以下操作:

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.