Przejdź do głównej zawartości

Mechanizm szyfrowania konfiguracji


Mechanizm szyfrowania konfiguracji wykorzystywany jest do zabezpieczenia (zaszyfrowania) części konfiguracji naszej aplikacji – tej która zawiera dane dostępowe do baz danych i innych zabezpieczonych komponentów, z którymi łączy się aplikacja (np. serwer SMTP, serwer Active Directory).

Sposób działania​

Dane szyfrowane są za pomocą algorytmu AES, który wymaga podania klucza szyfrującego. Klucz szyfrujący jest 16 znakowym ciągiem bajtów, generowanym automatycznie, na podstawie wprowadzonego przez administratora hasła za pomocą algorytmu MD5.

System nie nakłada żadnych wymogów na złożoność hasła, pozostawiając to w gestii administratora.

ważne

Hasło podane przez administratora nie jest nigdzie zapisywane. Jego utrata powoduje utratę możliwości wykonywania operacji administracyjnych środowiska.

Każdy komponent środowiska potrzebuje mieć dostęp do klucza szyfrującego by móc odczytać (odszyfrować) konfigurację środowiska. Informacja o kluczu szyfrującym jest przekazywane do komponentów w sposób bezpieczny:

  1. w przypadku środowisk kontenerowych: jako zmienna środowiskowa,
  2. w przypadku środowisk On-premises i Developerskich: jako zaszyfrowany za pomocą Data Protection API wpis w pliku *.config.ini dla każdego komponentu
ważne

Skorzystanie z Data Protection API powoduje, że klucz zaszyfrowany w pliku *.config.ini może być odczytany wyłącznie na tej samej maszynie. Próba odczytania klucza na innej maszynie zakończy się niepowodzeniem.

Powyższy sposób zabezpieczenia klucza szyfrującego chroni przed jego wyciekiem w przypadku skopiowania na inną maszynę binariów aplikacji.

Wyłącznie jeden komponent zaszyfrowanego środowiska - archITekt Studio – dopuszcza i obsługuje próbę uruchomienia na innej maszynie niż pierwotnie był zainstalowany. Zostało to podyktowane względami praktycznymi, ułatwiającymi zarządzanie środowiskiem.

W przypadku uruchomienia archITekt Studio na maszynie, na której nie ma ono możliwości automatycznego odczytania wartości klucza szyfrującego, użytkownikowi wyświetlany jest monit proszący o podanie hasła administratora. Na tej podstawie generowany jest klucz szyfrujący, którym aplikacja próbuje odczytać konfigurację środowiska.

Zakres szyfrowanych danych​

Na zabezpieczonym środowisku elementy zaszyfrowanej konfiguracji obejmują:

  1. pliki konfiguracji projektu (project.json, default.runtime.json)

image

  1. pliki konfiguracji komponentów *.config.ini

image

  1. wpisy w tabeli konfiguracyjnej (baza *_CONFIG, tabela CONFIG_KEYS).

image

Wpisy są skonstruowane wg konwencji [prefiks]:[wartość], gdzie prefiks określa sposób zaszyfrowania danego wpisu:

  1. ENC1 oznacza zaszyfrowanie wpisu za pomocą klucza szyfrującego.
  2. DPAPI oznacza zaszyfrowanie wpisu za pomocą mechanizmu Data Protection API.
  3. ENV oznacza przechowywanie wpisu w zmiennej środowiskowej.

Dwa ostatnie mechanizmy stosowane są wyłącznie do zabezpieczenia danych klucza szyfrującego.

Domyślnie, instalowane środowisko szyfruje tą część konfiguracji, która związana jest z połączeniami z zewnętrznymi komponentami. Szyfrowane są również wartości kluczy systemowych wrażliwych z definicji (np. hasło do serwera SMTP), jeśli zostały podane w parametrze configKeys – patrz Klucze wrażliwe.

W przypadku korzystania z dodatkowej konfiguracji, dostarczanej przez administratora systemu, to on sam decyduje, które jej fragmenty mają być zaszyfrowane – oznaczając wybrane klucze jako wrażliwe.

Poniżej fragment pliku project.json z dodatkowymi zmiennymi środowiskowymi wprowadzonymi przez administratora. W tym przypadku administrator zdecydował się na zabezpieczenie wartości zmiennej third.secret.setting.

image

Klucze wrażliwe​

Klucz konfiguracyjny może być oznaczony jako wrażliwy (ang. sensitive). Dla takiego klucza:

  1. wartość jest przechowywana w postaci zaszyfrowanej – zarówno w plikach projektu (project.json, custom.project.json), jak i w tabeli CONFIG_KEYS,
  2. klucz jest ukryty na listach kluczy (kolumna CK_SENSITIVE w tabeli CONFIG_KEYS ma wartość 1),
  3. wartość klucza nie jest zapisywana w logach skryptów wdrożeniowych.

Szyfrowanie wykorzystuje hasło bezpieczeństwa środowiska (parametr SecurityPassword).

ostrzeżenie

Jeżeli środowisko nie ma hasła bezpieczeństwa, wartości kluczy wrażliwych pozostają niezaszyfrowane, a skrypt wyświetla ostrzeżenie. Oznaczenie klucza w tabeli CONFIG_KEYS i ukrywanie go na listach kluczy działają mimo to.

Szyfrowanie wartości i flaga CK_SENSITIVE to dwa niezależne mechanizmy: aplikacja odszyfrowuje każdą wartość z prefiksem ENC1: niezależnie od flagi, a sama flaga niczego nie szyfruje. Skrypty wdrożeniowe dbają o to, by dla klucza wrażliwego oba były ustawione.

Klucze systemowe wrażliwe z definicji​

Część kluczy systemowych jest wrażliwa z definicji – nie można tego zmienić. Wartość podana dla nich w parametrze configKeys jest szyfrowana automatycznie, bez dodatkowych parametrów. Są to:

GrupaKlucze
Serwer SMTPcommon.param.smtp_server, common.param.smtp_username, common.param.smtp_password
Active Directorycommon.connection.provider_ad, common.param.provider_ad_user, common.param.provider_ad_password, common.param.provider_ad_user_container, common.param.provider_ad_role_container
Konto usługcommon.param.servicehost_user, common.param.servicehost_password
Łańcuchy połączeńcommon.connection.db_data, common.connection.scheduler_data, common.connection.version_server, common.connection.provider_mzu, studio.connection.version_server, www.connection.sql_session_state
Autoryzacja i podpisycommon.auth.client.auth_api_client_secret, scheduler.auth.client.client_secret, common.auth.server_rsa_signing_key, scheduler.restapi.signingKey, common.param.user_token_secret_key
Adresycommon.url.adfs_metadata, common.url.provider_mzu
wskazówka

Lista może się zmieniać pomiędzy wersjami platformy. Aktualną listę dla danego obrazu zwraca skrypt ReleaseInfo.ps1 znajdujący się w katalogu obrazu (klucze z atrybutem "sensitive": true):

cd "C:\Program Files\VSoft\archITekt\Images\[nazwa obrazu]"
.\ReleaseInfo.ps1 -OutFile C:\Temp\release.json

Oznaczanie własnych kluczy jako wrażliwych​

Dowolny inny klucz – w szczególności własny klucz custom.* – można oznaczyć jako wrażliwy na dwa sposoby:

  1. podając jego nazwę w parametrze sensitiveConfigKeys skryptu tworzącego środowisko (np. OnPremisesCreate.ps1) lub skryptu Reconfigure.ps1,
  2. podając jego wartość w parametrze configKeys w postaci już zaszyfrowanej (np. za pomocą skryptu SecurityOperation.ps1 -Operation Encrypt, opisanego poniżej). Klucz, którego wartość w plikach projektu jest zaszyfrowana, skrypty uznają za wrażliwy i informują o tym w logu (Config key '...' has an encrypted value - adding it to ConfigKeysSensitivity).

Drugi sposób dotyczy także projektów utworzonych w starszych wersjach platformy: przy pierwszym uruchomieniu nowej wersji skryptów (instalacja / aktualizacja komponentów, Reconfigure.ps1) ich klucze z zaszyfrowaną wartością zostaną oznaczone jako wrażliwe automatycznie.

ostrzeżenie

Zaszyfrowana wartość nie oznacza jako wrażliwego klucza systemowego (zdefiniowanego przez platformę), który nie jest wrażliwy z definicji. Taki klucz można oznaczyć wyłącznie parametrem sensitiveConfigKeys.

Przy tworzeniu środowiska:

.\OnPremisesCreate.ps1 [...] -SecurityPassword "[hasło]" `
-configKeys @{ "custom.api.url" = "https://api.example.com"; "custom.api.token" = "abc123" } `
-sensitiveConfigKeys "custom.api.token"

W istniejącym środowisku (skrypt Reconfigure.ps1):

# oznaczenie klucza jako wrażliwego (wartość zapisana w projekcie zostanie zaszyfrowana)
.\Reconfigure.ps1 -pathProjectFolder "[katalog projektu]" -SecurityPassword "[hasło]" `
-sensitiveConfigKeys "custom.api.token"

# nadanie wartości i oznaczenie w jednym wywołaniu
.\Reconfigure.ps1 -pathProjectFolder "[katalog projektu]" -SecurityPassword "[hasło]" `
-configKeys @{ "custom.api.token" = "nowa-wartosc" } -sensitiveConfigKeys "custom.api.token"

# zdjęcie oznaczenia (wartość zostanie odszyfrowana)
.\Reconfigure.ps1 -pathProjectFolder "[katalog projektu]" -SecurityPassword "[hasło]" `
-notSensitiveConfigKeys "custom.api.token"

Zasady:

  1. Parametry sensitiveConfigKeys i notSensitiveConfigKeys przyjmują listę nazw kluczy, np. -sensitiveConfigKeys @("klucz.a", "klucz.b"). Przy wywołaniu skryptu spoza PowerShella (np. pwsh Reconfigure.ps1 ... uruchamiane przez docker compose run) można podać jeden napis z nazwami rozdzielonymi przecinkami: -sensitiveConfigKeys klucz.a,klucz.b.
  2. Podaje się wyłącznie nazwy kluczy, bez wskazania węzła (NODE). Oznaczenie dotyczy klucza bez węzła oraz wszystkich jego wartości dla poszczególnych węzłów (nazwa zmiennej@nazwa node). Nie można oznaczyć klucza jako wrażliwego tylko dla jednego węzła.
  3. Skrypt sprawdza parametry w fazie weryfikacji, przed wprowadzeniem jakichkolwiek zmian, i kończy się błędem, jeżeli:
    • nazwa zawiera wskazanie węzła (nazwa.klucza@węzeł),
    • nazwa zawiera znaki inne niż litery (bez znaków narodowych), cyfry, ., -, _,
    • nazwa jest dłuższa niż 255 znaków,
    • ten sam klucz jest podany w obu parametrach,
    • parametr notSensitiveConfigKeys wskazuje klucz wrażliwy z definicji.
  4. Oznaczenie jest zapamiętywane w plikach projektu i obowiązuje przy każdej kolejnej instalacji.
  5. Zmiany wprowadzone skryptem Reconfigure.ps1 trafiają do bazy danych przy najbliższej aktualizacji komponentów środowiska – tak samo jak zmiany parametru configKeys.
  6. Zdjęcie oznaczenia (notSensitiveConfigKeys) odszyfrowuje wartość klucza w plikach projektu (dla wszystkich węzłów), a po aktualizacji komponentów klucz wraca na listy kluczy. Poza tym przypadkiem skrypty nigdy nie odszyfrowują wartości klucza.
  7. Nie można zdjąć oznaczenia z klucza wrażliwego z definicji.
  8. Klucz systemowy, który nie jest wrażliwy z definicji, można oznaczyć jako wrażliwy.
  9. Podanie w sensitiveConfigKeys klucza wrażliwego z definicji nie jest błędem – skrypt informuje, że pomija ten klucz (skipped - it is sensitive by definition), ponieważ i tak jest on traktowany jako wrażliwy.
  10. Dla klucza obecnego w plikach projektu flagę CK_SENSITIVE w bazie danych wyznaczają pliki projektu: klucz oznaczony jest wrażliwy, nieoznaczony – nie. Klucza, którego w plikach projektu nie ma (np. dodanego bezpośrednio w archITekt Studio), instalacja nie zmienia.
ostrzeżenie

Projekt z włączoną blokadą wersji obrazu (LockedImageVersion = „On”) jest obsługiwany przez skrypty obrazu, w którym go zablokowano. Parametry sensitiveConfigKeys i notSensitiveConfigKeys są dostępne tylko wtedy, gdy ten obraz je obsługuje – w przeciwnym razie skrypt zakończy się błędem nieznanego parametru.

Zapis w plikach projektu​

Oznaczenie kluczy jest przechowywane w plikach projektu w sekcji ConfigKeysSensitivity, obok sekcji ConfigKeys:

{
"ConfigKeys": {
"custom.api.token": "ENC1:zaOsj/6qVh/e8w9SCUe4AL/grkMNzHgTCl0mjzMpcs0=",
"custom.api.url": "https://api.example.com"
},
"ConfigKeysSensitivity": {
"custom.api.token": true
}
}
  1. Sekcja ConfigKeysSensitivity znajduje się w pliku custom.project.json dla kluczy custom.* oraz w pliku project.json dla pozostałych kluczy.
  2. Sekcja zawiera wyłącznie klucze wrażliwe (wartość true). Klucze wrażliwe z definicji nie są w niej zapisywane.
  3. Oznaczenie należy zdejmować parametrem notSensitiveConfigKeys, a nie ręczną edycją pliku – po ręcznym usunięciu wpisu zaszyfrowana wartość ponownie oznaczy klucz jako wrażliwy przy kolejnym uruchomieniu skryptów.
  4. Wartość klucza wrażliwego wpisaną ręcznie do pliku jawnym tekstem instalacja zapisze do bazy danych w postaci zaszyfrowanej. Sam plik zostanie zaszyfrowany przy najbliższym uruchomieniu skryptu Reconfigure.ps1.

Kolejny rozdział opisuje sposoby administracyjnego zarządzania szyfrowanymi ustawieniami środowiska.

wskazówka

Wygodne zarządzanie zmiennymi użytkownika i ich szyfrowaniem wspierane jest przez narzędzie VSoft archITekt Launcher.

Administracja zaszyfrowanym środowiskiem​

Administrator ma możliwość zarządzania zaszyfrowanym środowiskiem:

  1. Zarówno za pomocą standardowych skryptów instalacyjnych umożliwiających zaszyfrowanie otwartego środowiska, usunięcie szyfrowania ze środowiska oraz zmianę hasła szyfrującego, a co za tym idzie również klucza szyfrującego na środowisku.
  2. Samodzielne, z linii poleceń zaszyfrowanie wartości i deszyfrowanie elementów konfiguracji.

Opis działania parametrów związanych z szyfrowaniem w ramach skryptów instalacyjnych znajduje się w odpowiednich rozdziałach.

Zmiana hasła bezpieczeństwa (Reconfigure.ps1 -NewSecurityPassword) przeszyfrowuje nowym kluczem wartości kluczy wrażliwych w obu plikach projektu (project.json, custom.project.json) oraz w tabeli CONFIG_KEYS. Usunięcie hasła bezpieczeństwa (Reconfigure.ps1 -RemoveSecurityPassword) odszyfrowuje je – od tej chwili wartości kluczy wrażliwych są przechowywane jawnym tekstem (oznaczenie kluczy jako wrażliwych pozostaje).

Pozostałe, administracyjne operacje na pojedynczych zaszyfrowanych danych są możliwe do wykonania za pomocą skryptu SecurityOperation.ps1:

Uruchomienie skryptu:

cd "C:\Program Files\VSoft\archITekt\Images\[nazwa obrazu]"
.\ SecurityOperation.ps1
-Operation [rodzaj operacji] `
-SecurityPassword [hasło] `
-Value [opcjonalna wartość wymagana przez operację]

Parametry:

  1. Operation – jedna z operacji: CreateKey, Encrypt, Decrypt, GetDpapiData
  2. SecurityPassword – hasło administratora, na podstawie którego generowany jest klucz szyfrujący
  3. Value – dane wejściowe wymagane przez operacje Encrypt oraz Decrypt

Przykłady użycia:

Wygenerowanie klucza szyfrującego

PS> .\SecurityOperation.ps1
-Operation CreateKey
-SecurityPassword "sample1"
ac46374a846d97e22f917b6863f690ad

Skrypt zwraca klucz szyfrujący na podstawie przekazanego hasła. Dla tego samego hasła każde uruchomienie skryptu wygeneruje ten sam klucz szyfrujący.

Zakodowanie klucza szyfrującego za pomocą mechanizmu Data Protection API

PS>; .\SecurityOperation.ps1
-Operation GetDpapiData
-SecurityPassword "sample1"
DPAPI:AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAFSP(..)9FEQ==

Skrypt generuje klucz szyfrujacy na podstawie podanego hasła i koduje go za pomocą Data Protection API, tak, że jego odczytanie jest możliwe wyłącznie na maszynie, na której uruchomiono skrypt. Dla tego samego hasła każde uruchomienie skryptu wygeneruje poprawny, lecz różny ciąg zaszyfrowanych znaków poprzez użycie mechanizmu soli.

Zaszyfrowanie danych

.\SecurityOperation.ps1
-Operation Encrypt
-SecurityPassword "sample1"
-Value "value1"
ENC1:gJXzvjoAIgGkFZtn+tMH7X/XeOH0X8BJPlC4gmXAQEI=

Skrypt koduje wartość “value1” za pomocą klucza szyfrującego, wygenerowanego na podstawie hasła „sample1”. Powyższy skrypt może być użyty do zakodowania wartości parametru konfiguracyjnego do dodania do konfiguracji technicznej. Dla tych samych wartości i tego samego hasła każde uruchomienie skryptu wygeneruje poprawny, lecz różny ciąg zaszyfrowanych znaków poprzez użycie mechanizmu soli.

Odszyfrowanie danych

PS C:\Program Files\VSoft\archITekt\Images\Dev> .\SecurityOperation.ps1
-Operation Decrypt
-SecurityPassword "sample1"
-Value "ENC1:gJXzvjoAIgGkFZtn+tMH7X/XeOH0X8BJPlC4gmXAQEI="
value1

Skrypt dekoduje wartość “value1” za pomocą klucza szyfrującego, wygenerowanego na podstawie hasła „sample1”. Powyższy skrypt może być użyty do sprawdzenia zawartości zaszyfrowanej danej z konfiguracji technicznej.

Zobacz również​

Konfiguracja techniczna aplikacji

Mechanizm łączenia konfiguracji

Narzędzie DatabaseUpgrader