2009-08-24 10 views

Odpowiedz

9

Nie mogę wymyślić żadnej okoliczności, w której połączenie z Array.Clear zostanie kiedykolwiek zoptymalizowane, a nawet gdyby mogło być zoptymalizowane tylko w przypadkach, w których Twój byte[] został już wyczyszczony.

Edit: Coś innego do rozważenia byłoby dowiedzieć się, czy SecureString wdrażanie Ramowej byłaby przydatna w sytuacji:

SecureString obiekt jest podobny do String obiektu w tym, że ma tekstu wartość. Jednak wartość obiektu SecureString jest automatycznie szyfrowane, mogą być modyfikowane aż aplikacja oznacza go jako tylko do odczytu, a mogą zostać usunięte z pamięci komputera przez albo aplikacji lub śmieci NET Framework kolektora

+1

Jeśli nikt nie może jej odczytać tablicę po to został skasowany, a następnie może nie optymalizować przez kompilator nie czyszcząc go? – Gautam

+0

Jako punkt końcowy: kiedy mówisz _kompilator_, masz na myśli kompilator C# lub kompilator JIT? –

1

Jeśli obawiasz się o Array.Clear, możesz zawsze po prostu Marshal. Kopiuj pustą tablicę bajtów na wrażliwe dane.

Na przykład, jak to (przy założeniu, że „dane” jest bajt [], zawierający informacje poufne)

 byte[] clear = new byte[data.Length]; 
     unsafe 
     { 
      fixed (byte* ptr = &data[0]) 
      { 
       Marshal.Copy(clear, 0, new IntPtr(ptr), data.Length); 
      } 
     } 
0

że wrażenie, że istnieje już technik, aby przy obecnym stanie RAM. Potem są też faceci z MIT, którzy błyskają trochę pamięci RAM, podnieśli ją i zabrali gdzieś indziej i utrzymali cały stan.

Tak więc, jeśli byłeś paranoikiem, możesz losowo napisać całą masę danych przez tablicę kilka razy.

+0

Zrobili to. Jednak atak ten zakłada dostęp do systemu fizycznego. Obrona w głębi ... – Spence

+0

Prawdziwą lekcją jest to, że nie umieszczasz tajemnic na kliencie, ponieważ twój klient zawsze może być narażony na szwank. – Spence

+0

@Spence: Tak, myślę, że to szalone, że mogą to zrobić. :) –

4

Nawet jeśli Array.Clear jest gotowy do wykonania (nie zoptymalizowany), myślę, że nadal możesz mieć problem. GC może przenosić obiekty dookoła sterty i nie ma gwarancji, że ślady oryginalnego bajtu zatrzymają się, jeśli zostały przeniesione z jednej lokalizacji do innej, zanim wywołano Array.Clear.

Może chcesz wypróbować SecureString, ProtectedData lub ProtectedMemory. Ale jeśli chcesz bardziej ręcznego podejścia, myślę, że będziesz musiał przynajmniej przypiąć tablicę bajtów, aby GC nie mógł jej przenieść. Sądzę, że SecureString również używa tej sztuczki.

0

Sztuczka, która działa z większością kompilatorów języka C, polega na zrobieniu czegoś takiego jak suma wszystkich elementów wyczyszczonej tablicy, a następnie zrobienia czegoś za pomocą tej sumy, np. Wydrukuj ją lub zwróć z wartością zwracaną. W ten sposób eliminacja martwego kodu nie wyeliminuje czyszczenia tablicy.

To powiedziawszy, czy jesteś pewien, że wystarczy wyczyścić tę tablicę? Rozważ wszystkie inne miejsca, w których wartość mogła również istnieć: bufor w formie, przekazywanie obiektów łańcuchowych, kluczowe wartości równoważne w obliczeniach pośrednich lub stronicowane na dysk. Zerowanie tej jednej tablicy powoduje, że dostajesz tylko 1% drogi. Musisz wyczyścić całą ścieżkę klucza.

1

Jeśli piszesz własną procedurę szyfrowania, moja rada brzmi: nie rób tego. Źle to zrobisz (tak jak ja, tak jak każdy, kto nie jest zabezpieczeniem, ekspert). Użyj dobrze znanej, przetestowanej biblioteki.

(Jeśli nie, nieważne!) :)

+1

W pewnym momencie musisz wywoływać bibliotekę, a będziesz musiał wiedzieć, jak radzić sobie z sekretami, do których przechodzisz, i z biblioteki; w przeciwnym razie nie można utworzyć bezpiecznego oprogramowania. –

+0

@JirkaHanika Uzgodniony. – TrueWill