Spring Boot как скрыть пароли в файле свойств

81

Spring Boot использует файл свойств, и, по крайней мере, по умолчанию пароли представлены в виде обычного текста. Можно ли их как-то скрыть / расшифровать?

user1340582
источник

Ответы:

87

Вы можете использовать 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
Федерико Пьяцца
источник
2
Не могли бы вы объяснить более подробно, используя gradle @Frerica Piazza
testuser
Непонятно, как использовать с maven. вы передаете какое-то имущество, а что дальше? Где файл собственности? как записать это значение в код?
gstackoverflow
1
@FedericoPiazza Не mvn -Djasypt.encryptor.password=supersecretz spring-boot:runбудет отображаться в psвыводе, раскрывая пароль?
Srki Rakic
1
@SrkiRakic ​​да, конечно. Это только для разработки, если вы хотите его для производства, вы должны использовать переменные среды. Spring boot позволяет использоватьJASYPT_ENCRYPTOR_PASSWORD
Федерико Пьяцца
1
ха-ха, а как это попадает в переменные окружения? Вероятно, из другого файла, такого как определение службы: D Также jasypt устарел, когда дело доходит до получения пароля, поэтому убедитесь, что вы используете полностью случайный 32-
значный
14

ОБНОВЛЕНИЕ: я заметил, что люди проголосовали против этого, поэтому я должен сказать, что, хотя это не идеальное решение, но оно работает и приемлемо в некоторых случаях использования. 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);

Примечание. Возможно, вам придется перезагрузить компьютер после установки переменной среды. Для окон:

В Windows

Обратитесь к этой документации для получения дополнительной информации.

Санджай Рават
источник
25
Я не думаю, что установка мастер-пароля в переменных среды - такая хорошая идея. Пароль теперь более открыт, чем необходимо. Обеспечение его запуска, как показано Федерико, менее уязвимо и более «безопасно», чем установка его в среде.
Jaavaaan
Да, это не так, если вы используете общий компьютер. Но если вы единственный администратор своего компьютера, то другие пользователи не могут видеть переменные env. Я ответил на скрытую часть и на более легкую. Но да, я согласен, что метод, предложенный Федерико, намного лучше.
Санджай Рават,
См .: diogomonica.com/2017/03/27/…
Book Of Zeus
11

К уже предложенным решениям могу добавить возможность настройки внешнего Secrets Managerтипа Vault .

  1. Настроить Vault Server 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>

Добавьте свойства конфигурации 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) {
    // …
  }
}
J-Alex
источник
+1 за это решение. Лучше всего использовать такую ​​систему, как vault / etcd (или любую другую). diogomonica.com/2017/03/27/…
Book Of Zeus
3
-1, потому что это не объясняет, как защищен «главный» ключ (VAULT_TOKEN). Откуда взялась переменная окружения VAULT_TOKEN? Как это защищено? Не защищая этот ключ, злоумышленник может использовать его для извлечения секретов из хранилища, используя код, упакованный в банку Spring Boot.
corporatedrone
Также главной проблемой является обеспечение безопасности продукта. Итак, об этом нужно говорить здесь. Руководство по средам разработки / контроля качества, если все в порядке.
sofs1
Это работает, когда паролей много. Он работает с одним паролем для подключения, но забавно сказать, поместите пароль хранилища в среду, чтобы вам не нужно было помещать другой пароль в ту же среду.
Ли
0

Если вы используете довольно популярную в 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

жало
источник
0

Мое решение для скрытия пароля DB в приложении Spring Boot application.properties реализовано здесь .

Сценарий: какой-то поддельный пароль, уже считанный и сохраненный из application.properties при запуске, в глобальном объекте Spring ConfigurableEnvironment будет программно заменен во время выполнения на настоящий пароль DB. Настоящий пароль будет считываться из другого файла конфигурации, сохраненного в безопасном месте вне проекта.

Не забывайте: вызовите Bean из основного класса с помощью:

@Autowired
private SchedUtilility utl;
Яков Сенатов
источник
0

Помимо популярных решений K8s, jasypt или vault, существует также Karmahostage . Это позволяет вам делать:

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

Он работает так же, как jasypt, но шифрование происходит в специальном Saas-решении, к которому привязана более детальная модель ACL.

Qkyrie
источник