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
Spring Boot how to hide passwords in properties file
提问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 @Value
annotation
使用@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.sh
to export theJASYPT_ENCRYPTOR_PASSWORD
variable#!/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.properties
file 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 configuration
class:
在你的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:
注意:您可能需要在设置环境变量后重新启动。对于窗户:
Refer this Documentationfor more info.
有关更多信息,请参阅此文档。
回答by J-Alex
To the already proposed solutions I can add an option to configure an external Secrets Manager
such as Vault.
对于已经提出的解决方案,我可以添加一个选项来配置外部,Secrets Manager
例如Vault。
- Configure Vault Server
vault server -dev
(Only for DEV and not for PROD) - Write secrets
vault write secret/somename key1=value1 key2=value2
- Verify secrets
vault read secret/somename
- 配置 Vault 服务器
vault server -dev
(仅适用于 DEV,不适用于 PROD) - 写秘密
vault write secret/somename key1=value1 key2=value2
- 验证秘密
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_TOKEN
as 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