2009-04-24 12 views
20

È necessario archiviare e crittografare una password in un file (preferibilmente di testo), che in seguito sarà necessario poter decodificare. La password è per un altro servizio che uso e deve essere inviato lì in testo chiaro (su SSL). Questo non è qualcosa che posso cambiare. Quali sono le migliori pratiche in questo settore? Come si può ottenere un certo grado di protezione della password da parte degli utenti malintenzionati?Le migliori pratiche per crittografare e decifrare le password? (C# /. NET)

La mia piattaforma è WinForms con C# /. NET 3.5.

Grazie.

+3

Dovrebbe essere intitolato "Procedure ottimali per la crittografia delle password", poiché la decrittografia delle password è decisamente NON la procedura migliore. – devlord

+0

No, non dovrebbe; questa sarebbe una domanda completamente diversa. – Eyvind

+1

Le migliori pratiche per la decrittografia della password sono: NON FARLO. – saluce

risposta

2

Poiché si utilizza WinForms e .Net, il codice sarà visibile in MSIL, anche se è oscurato e pertanto il codice di decrittografia è visibile.

Da chi stai cercando di nascondere la password? L'utente dell'app non deve conoscere la password?

Penso che sarà necessario eseguire la convalida dell'utente e sarei tentato di inserire le chiavi nella decrittografia in un database separato e fornire un altro meccanismo per ottenere ciò che dovrebbe richiedere l'autenticazione. In questo modo puoi ottenere il codice di decodifica dall'app winforms.

Vorrei anche suggerire un servizio separato che viene eseguito per modificare regolarmente le chiavi di decrittografia della crittografia e aggiorna tutte le password nel database.

13

Suppongo che si voglia crittografare la password così come sarà sulla macchina dell'utente e che sarà (possibilmente) in grado di trovarla e usarla? Se è così, sei fondamentalmente fottuto - non importa cosa fai, dal momento che è nel dominio degli utenti che saranno in grado di ottenerlo e capire la crittografia e ottenere la password per la crittografia (ricorda che l'uso di Reflector - ed è cloni - non è fuori dalla portata della maggior parte) e decifrarlo e loro ce l'hanno. In breve, tutto ciò che stai facendo è offuscare la password, non proteggerla.

Quello che vorrei raccomandare è in realtà spostarlo fuori dal controllo dell'utente. Ad esempio, crea un servizio Web che comunica con il cliente e restituisce la password in modo sicuro quando richiesto. Ciò consente anche di cambiare la password, se necessario in futuro, oltre a fornire un modo per convalidare gli utenti legittimi.

+0

+1, ma come dovremmo proteggere l'accesso al servizio web di ritorno della password? –

+0

@Matthew qualsiasi sistema di autenticazione standard per i servizi funzionerebbe alla grande. –

+0

@Robert: ti piacerebbe elaborare? Se l'utente stesso può semplicemente chiamare il servizio, il punto di sicurezza è un po 'discutibile. Cosa non sto ottenendo qui? Grazie. – Eyvind

1

Crittografato in AES se è deve memorizzarlo in un file di testo.

AES è meglio conosciuto come Rijndael in C#

http://www.obviex.com/samples/Encryption.aspx

Meglio posto sarebbe il Registro di sistema, in quanto sarebbe proteggere gli altri utenti della macchina arrivare a esso.

Ancora non è il modo migliore per archiviarlo da qualsiasi parte in cui un utente potrebbe essere in grado di raggiungere un pericoloso sviluppatore decente in grado di caricare l'app in riflettore e trovare la chiave.

Oppure c'è System.Security.Cryptography.ProtectedData suggerito da qualcun altro.

Il meglio che si possa fare su una macchina è creare un certificato e crittografarlo/decodificarlo con esso caricato e bloccato nel keystore della macchina. (È necessario gestire la password del certificato inclusa nel codice)

+1

"Il posto migliore sarebbe il registro, poiché proteggerebbe gli altri utenti della macchina. L'archiviazione nel Registro di sistema o in un file di testo non influisce sull'accesso degli altri utenti della macchina. – Joe

+0

@Joe, HKEY_CURRENT_USER non è accessibile da altri utenti della macchina. Hanno il loro HKCU. Amministratore escluso, naturalmente. http://en.wikipedia.org/wiki/Windows_registry E poi c'è questo: http: //blogs.msdn.com/bclteam/archive/2006/01/06/509867.aspx –

+0

Ma hai ragione, io Non sono innamorato della mia risposta, ma con informazioni limitate su ciò che deve lavorare gli sto dando delle opzioni. Personalmente, mi piace usare un webservice/aspx per proxy la sua password per l'utente, ma poi deve ottenere un certificato SSL ecc. –

0

Non memorizzare la password come parte del codice. A parte i problemi di decompilazione e affidamento sulla sicurezza attraverso l'oscurità, se si modifica la password è necessario ricompilare e ridistribuire la propria applicazione.

Memorizzare la password come un servizio Web o in un database a cui l'applicazione ha accesso. Stai comunicando con un servizio sul Web, quindi sarai connesso, dopotutto.

0

Una delle cose più importanti sono le autorizzazioni sul file. Anche se il contenuto è crittografato, devi assicurarti che solo i processi che hanno bisogno di accedere al file possano leggerlo.

6

System.Security.Cryptography.ProtectedData nell'assembly System.Security utilizza alcune API di Windows per crittografare i dati con una password che solo conosce.

Uno dei possibili usi sarebbe quello di disporre di un servizio di Windows che esegue effettivamente l'operazione che richiede la password. L'applicazione che l'utente interagisce con le chiamate nel servizio tramite servizio remoto o WCF. Finché il servizio utilizza DataProtectionScope.CurrentUser e l'utente del servizio è diverso da quello dell'utente connesso, la password dovrebbe essere abbastanza sicura.

Questo naturalmente presuppone che gli utenti stiano correndo come utenti limitati che non possono modificare il servizio o eseguire il programma come utente del servizio.

7

Perché è necessario per decifrare la password? Solitamente un hash salato della password viene memorizzato e confrontato. Se si cripta/decrittografa la password, si ha di nuovo la password come testo normale e questo è pericoloso. L'hash deve essere salato per evitare l'hash duplicato se alcuni utenti hanno le stesse password. Per il sale si può prendere il nome utente.

HashAlgorithm hash = new SHA256Managed(); 
string password = "12345"; 
string salt = "UserName"; 

// compute hash of the password prefixing password with the salt 
byte[] plainTextBytes = Encoding.UTF8.GetBytes(salt + password); 
byte[] hashBytes = hash.ComputeHash(plainTextBytes); 

string hashValue = Convert.ToBase64String(hashBytes); 

Si può calcolare l'hash salata della password e memorizzare che all'interno del file. Durante l'autenticazione si calcola di nuovo l'hash dalle voci dell'utente e si confronta questo hash con l'hash della password memorizzata. Dal momento che dovrebbe essere molto difficile (la sua non impossibile, sempre una questione di tempo) per ottenere il testo in chiaro da un hash della password è protetta dalla lettura come testo normale di nuovo.

Suggerimento: non memorizzare o inviare una password non crittografata. Se ottieni una nuova password, la crittografia è il prima possibile!

+1

Come indicato nella domanda, devo decifrarlo perché il servizio accetta solo una password in forma non criptata. – Eyvind

+0

Se non riesci ad evitarlo, utilizzerei AES, ma tieni presente che è possibile leggere qualsiasi chiave di crittografia dall'assieme, quindi non è davvero salvabile. – Enyra

+0

Ciao, La crittografia SHA256 è abbastanza buona per il programma che memorizza le password in un file di testo normale? Sto cercando i metodi di descrizione per il mio programma di memorizzazione della password, e non sono sicuro di quale dovrei usare. – HelpNeeder

0

Dal momento che è necessario inviare la password in forma non cifrata attraverso la rete, non c'è niente che puoi fare per proteggere al 100%.

AES è abbastanza buono se avete bisogno di memorizzare in locale, e parlando di disasms, sniffer di rete, ecc non è particolarmente buona contropartita argomento becuase la stessa cosa può essere fatto con qualsiasi programma (certo, ASM è più difficile poi CIL ma è un punto minior).

Tale password di protezione è abbastanza buono per evitare casuale pick up, non impedire la decodifica da proffesionals.

+0

Come ha detto, è crittografato tramite SSL –

+0

La password è per un altro servizio che utilizzo e deve essere inviato lì in testo chiaro (su SSL) – majkinetor

1

Ho appena implementato qualcosa di simile per l'archiviazione di una password fornita dall'utente. Ho convertito il risultato crittografato in una stringa codificata in base 64, in modo da poterlo facilmente archiviare nelle impostazioni utente della mia applicazione.

Dalla tua domanda, sembra che l'utente malintenzionato è in realtà utilizzando la vostra applicazione, quindi questo fornirà solo offuscamento. Sebbene nessuna chiave venga rivelata attraverso l'uso di Reflector, il testo in chiaro sarebbe visibile in un debugger.

static byte[] entropy = { 65, 34, 87, 33 }; 

public string Password 
{ 
    get 
    { 
     if (this.EncryptedPassword == string.Empty) 
     { 
      return string.Empty; 
     } 

     var encrypted = Convert.FromBase64String(this.EncryptedPassword); 
     var data = ProtectedData.Unprotect(encrypted, entropy, DataProtectionScope.CurrentUser); 
     var password = Encoding.UTF8.GetString(data); 
     return password; 
    } 
    set 
    { 
     if (value == string.Empty) 
     { 
      this.EncryptedPassword = string.Empty; 
      return; 
     } 

     var data = Encoding.UTF8.GetBytes(value); 
     var encrypted = ProtectedData.Protect(data, entropy, DataProtectionScope.CurrentUser); 
     var stored = Convert.ToBase64String(encrypted); 
     this.EncryptedPassword = stored; 
    } 
} 
Problemi correlati