2010-09-24 12 views
13

Questa domanda segue un suggerimento fatto da @sharptooth in this related question.Come scrivere una classe sicura per la password?

È possibile modificare il numero std::string in modo da renderlo sicuro per la password?

In caso contrario, quali sarebbero le linee guida per scrivere una classe di gestione delle password (quindi una classe che presta grande attenzione a ciò che scrive in memoria e la cancella prima della distruzione)?

+1

1) utilizzare std: wstring, 2) push 0x2022 invece di simboli di password: o) Seriamente, se si teme che altri processi annusino qualcosa dalla memoria, aggiungere/rimuovere qualche maschera (xor?) – alxx

+0

@alxx : Come utilizzare 'std :: wstring' invece di' std :: string' essere più sicuro?! Mi sto perdendo qualcosa ? – ereOn

+1

0x2022 è un simbolo di proiettile. Prendilo? :) – alxx

risposta

19

Sì, prima definire un allocatore personalizzato:

template <class T> class SecureAllocator : public std::allocator<T> 
{ 
public: 
    template<class U> struct rebind { typedef SecureAllocator<U> other; }; 

    SecureAllocator() throw() {} 
    SecureAllocator(const SecureAllocator&) throw() {} 
    template <class U> SecureAllocator(const SecureAllocator<U>&) throw() {} 

    void deallocate(pointer p, size_type n) 
    { 
     std::fill_n((volatile char*)p, n*sizeof(T), 0); 
     std::allocator<T>::deallocate(p, n); 
    } 
}; 

Questo allocatore di zeri memoria prima deallocando. Ora è Typedef:

typedef std::basic_string<char, std::char_traits<char>, SecureAllocator<char>> SecureString; 

Tuttavia c'è un piccolo problema, std :: string può utilizzare l'ottimizzazione stringa piccola e memorizzare alcuni dati all'interno di sé, senza l'allocazione dinamica. Quindi si deve esplicitamente chiaro su distruzione o allocare sul mucchio con il nostro allocatore personalizzato:

int main(int, char**) 
{ 
    using boost::shared_ptr; 
    using boost::allocate_shared; 
    shared_ptr<SecureString> str = allocate_shared<SecureString>(SecureAllocator<SecureString>(), "aaa"); 

} 

Questo garantisce che tutti i dati viene azzerato prima della deallocazione, compresa la dimensione della stringa, per esempio.

+5

Non usare 'std :: fill_n', usa qualcosa come' SecureZeroMemory() '(http://msdn.microsoft.com/en-us/library/aa366877(VS.85).aspx) - con' std :: fill_n' il compilatore potrebbe ottimizzare la cancellazione. – sharptooth

+0

C'è anche un tweak per forzare 'std :: string' a cancellare lo spazio quando il codice chiamante fa accorciare la stringa - ad esempio rimuove i primi N elementi e quindi la coda viene spostata" a sinistra "e lascia i caratteri" a destra "? – sharptooth

+1

@sharptooth SecureZeroMemory non è standard e volatile impedisce l'ottimizzazione. Sì, se non ci sono chiamate di sistema alcuni dati potrebbero rimanere in memoria prima che la CPU svuoti la cache. – ybungalobill

Problemi correlati