2014-09-03 31 views
13

Nella mia applicazione WPF voglio consentire agli amministratori di testare una connessione al database utilizzando la sicurezza integrata per vari altri utenti. Quindi ho un modulo che consente all'amministratore di inserire il dominio, il nome utente e la password e quindi testarlo. Sono in grado di gestire in modo sicuro la password fino a quando chiamo LogonUser nel advapi32.dll che prende un string passwordWindows protetto Impersonificazione?

LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle) 

Ho scritto una funzione di utilità che converte il SecureString in una stringa il più sicuro possibile, e poi im chiamata sulla password nella chiamata LogonUser:

LogonUser(UserName, Domain, Helper.ConvertSafely(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle) 

Dal momento che la firma per LogonUser prende una stringa, a meno che LogonUser sta prendendo cura della password nella sua esecuzione, potrebbe essere ancora sul mio stack di chiamate in testo normale dopo la chiamata ritorna. C'è un modo più sicuro per impersonare un utente in cui posso essere sicuro che la PW è sicura per tutto il tempo?

Fondamentalmente tutto ciò di cui ho bisogno è un WindowsImpersonationContext ma mi piacerebbe acquistarlo senza che la password sia mai stata scritta in chiaro.

+0

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

+0

Buona domanda, in realtà. Ma se sei veramente preoccupato per la sicurezza, allora ti suggerisco di considerare anche le fughe di sicurezza non tecniche: i tuoi amministratori non devono avere, né richiedere, alcuna conoscenza delle password dei tuoi utenti. Il fatto che tu stia creando una schermata di nome utente/password suggerisce che l'amministratore inserirà le credenziali dell'utente. Questo mi sembra molto sbagliato. (E se non sono gli amministratori, ma gli utenti stessi, che inseriranno le loro credenziali, in primo luogo, 'RUNAS' l'applicazione con il proprio login, e non sarà necessario eseguire la rappresentazione.) – stakx

+0

il campo di input del modulo originale utilizza comunque una stringa regolare? Inoltre, potresti essere interessato a semplificare il codice 'LogonUser' con la mia libreria [SimpleImpersonation] (https://github.com/mj1856/SimpleImpersonation), come descritto [qui] (http://stackoverflow.com/a/7250145/634.824). Anche se non uso 'SecureString' neanche lì. –

risposta

4

Se l'utente che si desidera impersonare è già connesso alla macchina (ad esempio in un'altra sessione), qui è una risposta: Is it possible for a Windows service impersonate a user without a password?

Se non lo è, si dovrà fornire una password per LogonUser. E questa password dovrà risiedere almeno una piccola quantità di tempo, così com'è, in memoria perché è il modo in cui LogonUser è definito. Nota: non tutti i pacchetti auth richiedono password (come la biometrica o la smart card: Windows Authentication Overview).

Quindi, se davvero vuoi la rappresentazione, da qualche parte dovrai passare una password. In questo caso, assicurati di utilizzare il codice postlagerkarte di Microsoft per questo: Marshal.SecureStringToGlobalAllocUnicode Method sample code

Non puoi davvero fare molto di più.

6

All'interno dell'applicazione gestita è possibile utilizzare la classe SecureString per gestire le informazioni riservate. Di solito non è necessario eseguire il proprio meccanismo di stringa sicuro.

Poco prima di eseguire il pinvoke in LogonUser, si passa quindi alla copia non gestita di della password SecureString. Si utilizza il metodo Marshal.SecureStringToGlobalAllocUnicode per questo. Quindi non c'è mai un oggetto gestito nel dominio dell'app che rappresenta la password.

È possibile trovare il codice di esempio nell'articolo this.

Se si richiede ancora più sicurezza, suggerirei di disabilitare la connessione diretta al database dai client wpf. È possibile introdurre un livello intermedio. La sicurezza viene così spostata dai client a questo unico server. La comunicazione tra Client e App-Server è crittografata e solo il server delle app comunica con il database.

+0

questo è esattamente quello che sto facendo, sono solo preoccupato che la chiamata LogonUser lascerà la password non protetta nello stack che è fuori dalle mie mani. – user1336827

+0

sì hai ragione. potresti voler renderlo più chiaro nella tua domanda. È sempre possibile impostare un punto di interruzione sulla voce LogonUser API e eseguire il dump dello stack di chiamate. Quindi la domanda riguarda più la funzione nativa LogonUser. – Postlagerkarte

+0

Non sono sicuro di poter rendere la domanda molto più chiara, ci ho provato. Ma sì, il problema riguarda il codice non gestito LogonUser e se esiste un metodo più sicuro per acquisire un WindowsImpersonationContext senza doversi preoccupare di come il codice non gestito stia gestendo la password, che sembra utilizzarlo in testo normale. – user1336827

1

Aggiornamento:

si potrebbe implementare un crittografato app.config. È possibile farlo attraverso diversi approcci:

Così come questo dovrebbe funzionare, è quando un amministratore inserisce le credenziali che si decrittografare i app.config modificare la chiave/valore con le nuove credenziali. Quindi, una volta inserito, crittografa nuovamente il file di configurazione.

Quindi viene esposto in minima parte, ma anche i dati vengono inseriti tramite l'incapsulamento che aiuta anche a nasconderlo.

Questo è un approccio, anche se un SecureString funzionerà è previsto un char[]. Che in alcuni casi potrebbe non essere l'ideale quando si interfaccia attraverso il advapi32.dll.

+0

Sono confuso. Come vengono passate le credenziali crittografate a LogonUser dalla configurazione? –

+0

la sicurezza nel mio codice non è un problema, la password è memorizzata in un SecureString, è quando chiamo il codice non gestito LogonUser sta usando la password in testo normale. – user1336827

+0

@ user1336827 Quindi il codice non gestito lo sta effettivamente chiamando in testo normale? – Greg