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.

  1. Настройте сервер vault server -dev Vault Server vault server -dev (только для DEV, а не для PROD)
  2. Записать секреты vault write secret/somename key1=value1 key2=value2 Записать 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>

Добавьте свойства конфигурации 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) {
    // …
  }
}