Spring Boot korzysta z pliku właściwości i przynajmniej domyślnie hasła są w postaci zwykłego tekstu. Czy można je w jakiś sposób ukryć / odszyfrować?
źródło
Spring Boot korzysta z pliku właściwości i przynajmniej domyślnie hasła są w postaci zwykłego tekstu. Czy można je w jakiś sposób ukryć / odszyfrować?
Możesz użyć Jasypt do szyfrowania właściwości, więc możesz mieć taką własność:
db.password=ENC(XcBjfjDDjxeyFBoaEPhG14wEzc6Ja+Xx+hNPrJyQT88=)
Jasypt umożliwia szyfrowanie właściwości przy użyciu różnych algorytmów, gdy uzyskasz zaszyfrowaną właściwość, którą umieścisz w pliku ENC(...)
. Na przykład możesz zaszyfrować w ten sposób przez Jasypt za pomocą terminala:
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=
Aby łatwo skonfigurować go za pomocą Spring Boot, możesz użyć jego startera jasypt-spring-boot-starter z identyfikatorem grupycom.github.ulisesbocchio
Pamiętaj, że będziesz musiał uruchomić aplikację przy użyciu tego samego hasła, którego użyłeś do zaszyfrowania właściwości. Możesz więc uruchomić swoją aplikację w ten sposób:
mvn -Djasypt.encryptor.password=supersecretz spring-boot:run
Lub używając zmiennej środowiskowej (dzięki luźnemu wiązaniu w butach sprężynowych):
export JASYPT_ENCRYPTOR_PASSWORD=supersecretz
mvn spring-boot:run
Możesz sprawdzić poniższy link, aby uzyskać więcej informacji:
https://www.ricston.com/blog/encrypting-properties-in-spring-boot-with-jasypt-spring-boot/
Aby użyć swoich zaszyfrowanych właściwości w swojej aplikacji, po prostu użyj ich jak zwykle, użyj dowolnej metody (Spring Boot łączy magię, w każdym razie właściwość musi być oczywiście w ścieżce klas):
Korzystanie z @Value
adnotacji
@Value("${db.password}")
private String password;
Lub używając Environment
@Autowired
private Environment environment;
public void doSomething(Environment env) {
System.out.println(env.getProperty("db.password"));
}
Aktualizacja: dla środowiska produkcyjnego, aby uniknąć ujawniania hasła w wierszu poleceń, ponieważ możesz wysyłać zapytania do procesów ps
, poprzednich poleceń history
itp. Itp. Możesz:
touch setEnv.sh
setEnv.sh
aby wyeksportować JASYPT_ENCRYPTOR_PASSWORD
zmienną
#! / bin / bash
eksportuj JASYPT_ENCRYPTOR_PASSWORD = supersecretz
. setEnv.sh
mvn spring-boot:run &
setEnv.sh
unset JASYPT_ENCRYPTOR_PASSWORD
mvn -Djasypt.encryptor.password=supersecretz spring-boot:run
pojawi się naps
wyjściu, ujawniając hasło?JASYPT_ENCRYPTOR_PASSWORD
AKTUALIZACJA: Zauważyłem, że ludzie głosowali w dół, więc muszę powiedzieć, że chociaż nie jest to idealne rozwiązanie, ale działa i jest akceptowalne w niektórych przypadkach użycia. Cloudfoundry używa zmiennych środowiskowych do wstrzykiwania poświadczeń, gdy Usługa jest powiązana z aplikacją. Więcej informacji https://docs.cloudfoundry.org/devguide/services/application-binding.html
A jeśli twój system nie jest współdzielony, to w przypadku rozwoju lokalnego jest to również dopuszczalne. Oczywiście bezpieczniejszy sposób jest wyjaśniony w odpowiedzi od @ J-Alex.
Odpowiedź:
Jeśli chcesz ukryć swoje hasła, najłatwiejszym rozwiązaniem jest użycie zmiennych środowiskowych w
application.properties
pliku lub bezpośrednio w kodzie.W
application.properties
:Następnie w swojej klasie konfiguracji:
@Autowired private Environment environment; [...]//Inside a method System.out.println(environment.getProperty("mypassword"));
W Twojej
configuration
klasie:@Value("${password}") private String herokuPath; [...]//Inside a method System.out.println(herokuPath);
Uwaga: po ustawieniu zmiennej środowiskowej może być konieczne ponowne uruchomienie. Dla Windowsa:
Więcej informacji można znaleźć w tej dokumentacji .
źródło
Spring Cloud Config Server pozwoli na tego typu zachowanie. Za pomocą JCE można ustawić klucz na serwerze i użyć go do zaszyfrowania właściwości aplikacji.
http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html
źródło
Do już proponowanych rozwiązań mogę dodać opcję konfiguracji zewnętrznego
Secrets Manager
typu Vault .vault server -dev
( tylko dla DEV, a nie dla PROD )vault write secret/somename key1=value1 key2=value2
vault read secret/somename
Dodaj następującą zależność do projektu SpringBoot:
Dodaj właściwości konfiguracyjne programu 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}
Przekaż
VAULT_TOKEN
jako zmienną środowiskową.Zapoznaj się z dokumentacją tutaj.
Istnieje projekt Spring Vault , którego można również użyć do uzyskiwania dostępu, przechowywania i odwoływania sekretów.
Zależność:
Konfigurowanie szablonu repozytorium:
@Configuration class VaultConfiguration extends AbstractVaultConfiguration { @Override public VaultEndpoint vaultEndpoint() { return new VaultEndpoint(); } @Override public ClientAuthentication clientAuthentication() { return new TokenAuthentication("…"); } }
Wstrzyknij i użyj 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(); } }
Użyj Vault
PropertySource
:@VaultPropertySource(value = "aws/creds/s3", propertyNamePrefix = "aws." renewal = Renewal.RENEW) public class Config { }
Przykład użycia:
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) { // … } }
źródło
W przypadku korzystania z dość popularnego w środowisku Spring Boot Kubernetes (K8S) lub OpenShift, istnieje możliwość przechowywania i pobierania właściwości aplikacji w czasie wykonywania. Ta technika nazywa się tajemnicami . W pliku konfiguracyjnym yaml dla Kubernetes lub OpenShift deklarujesz zmienną i symbol zastępczy dla niej, a po stronie K8S \ OpenShift deklarujesz rzeczywistą wartość, która odpowiada temu symbolowi zastępczemu. Szczegóły implementacji: K8S: https://kubernetes.io/docs/concepts/configuration/secret/ OpenShift: https://docs.openshift.com/container-platform/3.11/dev_guide/secrets.html
źródło
Moje rozwiązanie do ukrywania hasła DB w application.properties aplikacji Spring Boot zostało zaimplementowane tutaj .
Scenariusz: niektóre fałszywe hasła, które zostały już odczytane i zapisane z application.properties przy uruchomieniu, w globalnym obiekcie Spring ConfigurableEnvironment zostaną programowo zastąpione w Run-Time przez rzeczywiste hasło DB. Prawdziwe hasło zostanie odczytane z innego pliku konfiguracyjnego, zapisanego w bezpiecznym, zewnętrznym miejscu projektu.
Nie zapomnij: zadzwoń do Fasolki z klasy głównej z:
@Autowired private SchedUtilility utl;
źródło
Oprócz popularnych rozwiązań K8, jasypt czy vault, istnieje również Karmahostage . Umożliwia:
@EncryptedValue("${application.secret}") private String application;
Działa w ten sam sposób, co jasypt, ale szyfrowanie odbywa się na dedykowanym rozwiązaniu SaaS, z dołączonym bardziej szczegółowym modelem ACL.
źródło