2012-04-02 3 views
10

Chcę wyczyścić poufne dane z pamięci w mojej aplikacji na iOS. W systemie Windows użyłem SecureZeroMemory. Teraz, w iOS, używam zwykły stary memset, ale jestem trochę zaniepokojony kompilator może zoptymalizować go: https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/771-BSI.htmlJaki jest prawidłowy sposób czyszczenia poufnych danych z pamięci w systemie iOS?

fragment kodu:

NSData *someSensitiveData; 
memset((void *)someSensitiveData.bytes, 0, someSensitiveData.length); 

Odpowiedz

3

Parafrazując 771 BSI (Link patrz OP)

taki sposób, aby uniknąć wywołania memset zoptymalizowane przez kompilator jest uzyskanie dostępu do bufora ponownie po wywołaniu memset w taki sposób, że zmusza kompilator nie zoptymalizować lokalizację. Można to osiągnąć przez

*(volatile char*)buffer = *(volatile char*)buffer; 

po wywołaniu memset().

W rzeczywistości, można napisać secure_memset() funkcję

void* secure_memset(void *v, int c, size_t n) { 
    volatile char *p = v; 
    while (n--) *p++ = c; 
    return v; 
} 

(Kod pochodzi z 771-BSI. Dzięki Daniel Trebbien za wskazanie do ewentualnej wady poprzedniego wniosku kodu.)

Dlaczego volatile zapobiega optymalizacji? Zobacz https://stackoverflow.com/a/3604588/220060

UPDATE Proszę również przeczytać Sensitive Data In Memory bo jeśli masz adwersarza w systemie iOS, Twoje są już mniej lub bardziej wkręca zanim jeszcze próbuje odczytać, że pamięć. W podsumowaniu SecureZeroMemory() lub secure_memset() naprawdę nie pomagają.

+0

Pomyślałem, że może istnieje odpowiednik SecureZeroMemory() w iOS. Twoje rozwiązanie wygląda dobrze, ale co powiesz na "Rozwiązanie powinno być skuteczne na większości platform, ale zapoznaj się z dokumentacją platformy, aby sprawdzić, czy wystarczy odwoływać się do jednej postaci w ten sposób." – HyBRiD

+0

Myślę, że to tylko ostrożnie kręci się tam iz powrotem. Jest to podyktowane przez standard, że dostęp do zmiennych lotnych NIE jest zoptymalizowany. W rzeczywistości może się zdarzyć, że jeden znak jest portem sprzętowym, a dostęp do odczytu wyzwala coś na poziomie sprzętu. Z niestabilnością deklarujesz kompilatorowi, że wiesz lepiej od niego i że nawet nie myśli o próbie optymalizacji tego dostępu. A ponieważ dostęp ten zależy od elementu memset() przed nim, memset() nie zostanie zoptymalizowany. – nalply

+0

Twoja funkcja 'secure_memset' może nie być wystarczająca. Według http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf optymalizują kompilatory, które wyzerują tylko pierwszy bajt. –

0

Problemem jest NSData jest niezmienna i nie zrobić mieć kontrolę nad tym, co się dzieje. Jeśli bufor jest kontrolowany przez ciebie, możesz użyć dataWithBytesNoCopy: length: a NSData będzie działać jako opakowanie. Po zakończeniu możesz zapisać swój bufor.

Powiązane problemy