W kodzie często używamy klasy Stirng do przechowywania poufnych informacji takich jak np. hasło. Niestety często nie zdajemy sobie sprawy jak niebezpieczne jest takie rozwiązanie. String jest specjalnie zoptymalizowaną klasą przeznaczoną do przechowywania łańcucha znaków, która jednak nie jest odporna na wszelkie ataki związane z podglądaniem pamięci operacyjnej. W skrócie pisząc, wszelkie informacje klasa String trzyma w postaci jawnej. Korzystając więc z odpowiedniego oprogramowania, intruz może bez problemu podejrzeć co aplikacja trzyma w klasie String. Ponadto ze względów na wspomnianą optymalizację String posiada następujące wady(w kwestii bezpieczeństwa):
- Brak możliwości wyczyszczenia bufora String. Nawet gdy przypiszemy wartość NULL, napis pozostaje wciąż zapisany w pamięci.
- Garbage Collector może robić kopie wartości String. Napisy nie są przechowywane ciągle pod tym samym adresem.
- Brak jakiejkolwiek metody szyfrowania danych.
W środowisku .NET rozwiązaniem na powyższe problemy jest klasa System.Security.SecureString. Moim zdaniem jest dosyć niewygodna w użyciu, jednak i tak wartość z niej korzystać.
Przykład zapisania do SecureString wartości podanej przez użytkownika(4 znaki):
SecureString secureString = new SecureString(); secureString.AppendChar(Console.ReadKey().KeyChar); secureString.AppendChar(Console.ReadKey().KeyChar); secureString.AppendChar(Console.ReadKey().KeyChar); secureString.AppendChar(Console.ReadKey().KeyChar);
Następnie powinno się zablokować dostęp do wszelkich modyfikacji:
secureString.MakeReadOnly();
Wszelkie próby modyfikacji od tej chwili zakończą się wyrzuceniem wyjątku InvalidOperationException.
Zastanawiam się jak bardzo jest to przydatne. Zamkniemy sobie takie hasło w SecureString i co dalej? Żeby je użyć w np. connection string trzeba je stamtąd wyciągnąć znów do jawnej postaci. Aby rozpatrzyć uwierzytelnianie poprzez porównanie haseł w programie to znów trzeba je do jawnej postaci wyciągnąć lub te z którym porównujemy do SecureStringa – ale te zaś początkowo musiałoby być w postaci jawnej. “Korzystając więc z odpowiedniego oprogramowania, intruz może bez problemu podejrzeć co aplikacja trzyma.”