Wiele skryptów używa poświadczeń/haseł do realizacji określonych zadań. Automatyczna wysyłka wiadomości mailowej czy realizacja zapytania SQL będzie wymagała podania nazwy użytkownika i hasła. Często zdarza się, że administrator zapomina o bezpieczeństwie tworząc skrypt i wpisuje hasło otwartym tekstem. Nie trzeba nikomu mówić o tym że nie jest to dobra ani bezpieczna praktyka. Na szczęście mamy na to sprawdzone rozwiązanie.
PowerShell pozwala na wiele sposobów zarządzać poświadczeniami. Można przypisywać login i hasło do zmiennej:
$login = 'sprawdzone.it\administrator'
$haslo = 'B@rdz0Trudn3H@s10'
a nastąpienie używać tych zmiennych. Jak informowaliśmy powyżej jest to nie bezpieczne i nie zalecane – zwłaszcza w skryptach produkcyjnych. Można poświadczenia zapisywać podczas danej sesji z użyciem polecenia Get-Credential
$poswiadczenia = get-credential
Wtedy pojawi się monit o podanie loginu i hasła. Następnie system zaszyfruje hasło i będzie przechowywał przez czas trwania sesji pod podaną wyżej zmienną.
Nasz problem jest jednak troche inny o ile można pytać usera wykoującego jednorazowo lub na rządanie poprzez get-credential o poświadczenia o tyle w automatycznym skrypcie czy zadaniu to już nie możliwe.
I to własnie System.Security.SecureString jest rozwiązaniem naszego problemu z bezpieczeństwem hasła.
Samo rozwiązanie opiera się o Windows Data Protection API a dokładnie DPAPI (Data Protection Application Programming Interface) i jest używane w produktach Microsoft od dawna. Polega ono na szyfrowaniu określonego łańcucha znaków (w naszym przypadku hasła) z użyciem zmiennej ścisłe związanej z kluczem prywatnym danego profilu użytkownika. Taki zaszyfrowany łańcuch znaków możemy przechowywać np w pliku tekstowym. Dzięki temu hasło będzie „pod ręką” gotowe do użycia np jako zmienna ale nie możliwe do odczytania przez osobę postronną – nawet po otwarciu czy skopiowaniu pliku txt. Do użycia Windows Data Protection API posłużą nam dwa polecenia:
ConvertTo-SecureString
ConvertFrom-SecureString
Zaczynamy przygotowania pliku z zaszyfrowanym hasłem:
$haslo = Read-Host "Wprowadź hasło" –AsSecureString
Następnie zapisujemy zaszyfrowane hasło:
$haslo | ConvertFrom-SecureString | Set-Content C:\it\script\haslo.txt
Dla pewności sprawdzamy jeszcze jak wygląda zawartość takiego pliku:
get-content c:\it\script\haslo.txt
Mamy już zaszyfrowane hasło jak użyć go w skrypcie? Wybraliśmy drogę z plikiem zatem przeczytajmy jego zawartość i zamieńmy z powrotem z użyciem Windows Data Protection API do hasła:
$haslo = get-content C:\it\script\haslo.txt | ConvertTo-SecureString
Jeżeli chcemy użyć loginu i hasła w jednej zmiennej zmieniamy całość w obiekt Management.Automation.PSCredential
$poswiadczenia= new-object Management.Automation.PSCredential -ArgumentList $login, $haslo
Teraz taką zmienną możemy użyć jako hasło np przy wysyłce maila skryptem (odsyłamy do naszego wpisu) – całość wygląda dużo prościej niż myślicie:
$login = 'sprawdzone.it@gmail.com'
$haslo = get-content C:\it\script\haslo.txt | ConvertTo-SecureString
$poswiadczenia=new-object Management.Automation.PSCredential -ArgumentList $login, $haslo
$param = @{
SmtpServer = 'smtp.gmail.com'
Port = 587
UseSsl = $true
Credential = $poswiadczenia
Encoding = 'utf8'
From = 'sprawdzone.it@gmail.com'
To = 'info@sprawdzone.it'
Subject = 'mail wyslany skryptem'
Body = 'Mail wyslany ze skryptu z zaszyfrowanym haslem'
}
Send-MailMessage @param
Dzięki temu wzrasta poziom bezpieczeństwa naszych skryptów – szyfrować możemy dowolną zmienną nie tylko hasło. Zaszyfrowane dane nie muszą być trzymane w pliku! To dopiero początek – wkrótce kolejne wpisy.