Spring Загрузите, как скрыть пароли в файле свойств
Spring Boot использует файл свойств и, по крайней мере, по умолчанию, пароли имеют простой текст. Можно ли как-то скрыть/расшифровать эти данные?
Ответы
Ответ 1
Вы можете использовать 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 с идентификатором группы 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;
Или используя 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
export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
- Запустите файл с помощью
. setEnv.sh
- Запустите приложение в фоновом режиме с помощью
mvn spring-boot:run &
- Удалить файл
setEnv.sh
- Удалите предыдущую переменную среды с помощью:
unset JASYPT_ENCRYPTOR_PASSWORD
Ответ 2
Spring Сервер Cloud Config Server позволит использовать этот тип поведения. Используя JCE, вы можете настроить ключ на сервере и использовать его для шифрования свойств приложений.
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html
Ответ 3
Если вы хотите скрыть свои пароли, то самое простое решение - использовать переменные среды в файле 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]()
Для получения дополнительной информации обратитесь к этой документации.
ОБНОВЛЕНИЕ: Я заметил, что люди проголосовали против этого, поэтому я должен сказать, что, хотя это не идеальное решение, но это работает и приемлемо в некоторых случаях использования.
Cloudfoundry использует переменные среды для ввода учетных данных, когда служба привязана к приложению. Подробнее https://docs.cloudfoundry.org/devguide/services/application-binding.html
А также, если ваша система не является общей, то для локального развития это также приемлемо. Конечно, более безопасный и надежный способ объясняется в Ответе @J-Alex.
Ответ 4
К уже предложенным решениям я могу добавить опцию для настройки внешнего Secrets Manager
такого как Vault.
- Настройте сервер
vault server -dev
Vault Server vault server -dev
(только для DEV, а не для PROD) - Записать секреты
vault write secret/somename key1=value1 key2=value2
Записать vault write secret/somename key1=value1 key2=value2
- Проверить секреты
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
в качестве переменной среды.
Обратитесь к документации здесь.
Существует проект 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();
}
}
Используйте 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) {
// …
}
}