2012-09-30 8 views
72

Sto creando un'applicazione Windows, a cui è necessario accedere prima.
I dettagli dell'account sono costituiti da nome utente e password e devono essere salvati localmente.
È solo una questione di sicurezza, quindi altre persone che utilizzano lo stesso computer non possono vedere i dati personali di tutti.
Qual è il modo migliore/più sicuro per salvare questi dati? Come salvare in modo sicuro nome utente/password (locale)?

Non voglio usare un database, così ho provato alcune cose con i file di risorse.
Ma dal momento che sono un po 'nuovo con questo, non sono completamente sicuro di quello che sto facendo e dove dovrei cercare una soluzione.

+4

Prima di tutto, non salvare la password. Hash (possibilmente con un valore salt) e salvalo. – carlosfigueira

+0

"Utenti" intendi normali utenti Windows o qualcos'altro? (Penso che tu voglia dire che alcuni di voi posseggono "utenti" come normali utenti Windows già non possono vedere i reciproci dati ...) –

+0

Ho modificato il tuo titolo. Per favore vedi, "[Le domande dovrebbero includere" tag "nei loro titoli?] (Http://meta.stackexchange.com/questions/19190/)", dove il consenso è "no, non dovrebbero". –

risposta

120

Se si sta solo verificando/convalidando il nome utente e la password immessi, utilizzare la classe Rfc2898DerivedBytes (nota anche come funzione di derivazione chiave basata su password 2 o PBKDF2). Questo è più sicuro rispetto all'utilizzo di crittografia come Triple DES o AES perché non esiste un modo pratico per passare dal risultato di RFC2898DerivedBytes alla password. Puoi passare da una password al risultato. Vedi Is it ok to use SHA1 hash of password as a salt when deriving encryption key and IV from password string? per un esempio e discussione per .Net o String encrypt/decrypt with password c# Metro Style per WinRT/Metro.

Se si sta memorizzando la password per il riutilizzo, ad esempio fornendola a terzi, utilizzare Windows Data Protection API (DPAPI). Questo utilizza le chiavi generate e protette dal sistema operativo e l'algoritmo di crittografia Triple DES per crittografare e decrittografare le informazioni. Ciò significa che l'applicazione non deve preoccuparsi di generare e proteggere le chiavi di crittografia, una delle principali preoccupazioni quando si utilizza la crittografia.

In C#, utilizzare la classe System.Security.Cryptography.ProtectedData. Ad esempio, per cifrare un pezzo di dati, utilizzare ProtectedData.Protect():

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes(). 
byte[] plaintext; 

// Generate additional entropy (will be used as the Initialization vector) 
byte[] entropy = new byte[20]; 
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
{ 
    rng.GetBytes(entropy); 
} 

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy, 
    DataProtectionScope.CurrentUser); 

Conservare l'entropia e testo cifrato in modo sicuro, come ad esempio in una chiave di file o Registro di sistema con permessi impostati in modo che solo l'utente corrente in grado di leggerlo. Per ottenere l'accesso ai dati originali, utilizzare ProtectedData.Unprotect():

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy, 
    DataProtectionScope.CurrentUser); 

Nota che ci sono considerazioni di sicurezza aggiuntive. Ad esempio, evitare di memorizzare segreti come password come string.Le stringhe sono immutabili, in quanto non possono essere notificate in memoria, quindi qualcuno che guarda la memoria dell'applicazione o un dump della memoria potrebbe vedere la password. Utilizzare invece SecureString o un byte [] e ricordare di eliminarli o azzerarli non appena la password non è più necessaria.

+0

Ciao, ho provato questo, ma ho ottenuto un errore in entropy = rng.GetBytes (20) dicendo: Impossibile convertire da int a byte [] – Robin

+0

@CrispyGMR Ho risolto quel pezzo di codice nella risposta. Buona pesca. – akton

+0

Grazie mille. All'inizio usavo md5 per l'hashing, ma ero piuttosto scettico al riguardo. Questo sembra molto più sicuro. Ancora una domanda. Voglio salvare un po 'di dati come questo in un file di testo. Vedo che è solo un mucchio di caratteri casuali quando apro il mio file, ma è abbastanza sicuro farlo? O consigli un altro modo di memorizzare i dati? – Robin

6

Ho usato questo prima e penso che, al fine di assicurarsi che le credenziali persistere e in un migliore modo sicuro è

  1. poterle scrivere sul file di applicazione di configurazione utilizzando il ConfigurationManager classe
  2. proteggere la password utilizzando la classe SecureString
  3. quindi crittografarla utilizzando gli strumenti nello spazio dei nomi Cryptography.

Questo collegamento sarà di grande aiuto spero: Click here

3

DPAPI è proprio per questo scopo. Utilizzare DPAPI per crittografare la password la prima volta che l'utente entra, memorizzarla in un luogo sicuro (il registro utente, la directory dei dati dell'applicazione dell'utente, sono alcune scelte). Ogni volta che l'app viene avviata, controlla la posizione per vedere se esiste la tua chiave, se utilizza DPAPI per decrittografarla e consentire l'accesso, altrimenti negarla.