Spring Boot использует файл свойств, и, по крайней мере, по умолчанию пароли представлены в виде обычного текста. Можно ли их как-то скрыть / расшифровать?
Spring Boot использует файл свойств, и, по крайней мере, по умолчанию пароли представлены в виде обычного текста. Можно ли их как-то скрыть / расшифровать?
Ответы:
Вы можете использовать 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
экспорт JASYPT_ENCRYPTOR_PASSWORD = supersecretz
. setEnv.sh
mvn spring-boot:run &
setEnv.sh
unset JASYPT_ENCRYPTOR_PASSWORD
mvn -Djasypt.encryptor.password=supersecretz spring-boot:run
будет отображаться в ps
выводе, раскрывая пароль?
JASYPT_ENCRYPTOR_PASSWORD
ОБНОВЛЕНИЕ: я заметил, что люди проголосовали против этого, поэтому я должен сказать, что, хотя это не идеальное решение, но оно работает и приемлемо в некоторых случаях использования. Cloudfoundry использует переменные среды для ввода учетных данных, когда Служба привязана к приложению. Подробнее https://docs.cloudfoundry.org/devguide/services/application-binding.html
А также, если ваша система не используется совместно, то для локальной разработки это тоже приемлемо. Конечно, более безопасный и безопасный способ объясняется в ответе @ J-Alex.
Ответ:
Если вы хотите скрыть свои пароли, самое простое решение - использовать переменные среды в 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);
Примечание. Возможно, вам придется перезагрузить компьютер после установки переменной среды. Для окон:
Обратитесь к этой документации для получения дополнительной информации.
Spring Cloud Config Server допускает такое поведение. Используя JCE, вы можете установить ключ на сервере и использовать его для шифрования свойств приложения.
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html
К уже предложенным решениям могу добавить возможность настройки внешнего Secrets Manager
типа Vault .
vault server -dev
( только для DEV, а не для PROD )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) {
// …
}
}
Если вы используете довольно популярную в Spring Boot среду Kubernetes (K8S) или OpenShift, есть возможность сохранять и извлекать свойства приложения во время выполнения. Эта техника называется секретами . В вашем конфигурационном файле yaml для Kubernetes или OpenShift вы объявляете переменную и заполнитель для нее, а на стороне K8S \ OpenShift объявляете фактическое значение, которое соответствует этому заполнителю. Подробнее о реализации см .: K8S: https://kubernetes.io/docs/concepts/configuration/secret/ OpenShift: https://docs.openshift.com/container-platform/3.11/dev_guide/secrets.html
Мое решение для скрытия пароля DB в приложении Spring Boot application.properties реализовано здесь .
Сценарий: какой-то поддельный пароль, уже считанный и сохраненный из application.properties при запуске, в глобальном объекте Spring ConfigurableEnvironment будет программно заменен во время выполнения на настоящий пароль DB. Настоящий пароль будет считываться из другого файла конфигурации, сохраненного в безопасном месте вне проекта.
Не забывайте: вызовите Bean из основного класса с помощью:
@Autowired
private SchedUtilility utl;
Помимо популярных решений K8s, jasypt или vault, существует также Karmahostage . Это позволяет вам делать:
@EncryptedValue("${application.secret}")
private String application;
Он работает так же, как jasypt, но шифрование происходит в специальном Saas-решении, к которому привязана более детальная модель ACL.