2012-02-10 20 views
30

Desidero memorizzare in modo sicuro una password in chiaro su PC Windows. Attualmente sto utilizzando DPAPI CryptProtectData per crittografarlo, quindi archiviare il BLOB crittografato in un file in AppData locale dell'utente.Come si memorizzano e si recuperano le credenziali dal gestore di credenziali di Windows Vault?

In Windows 7, è presente Windows Vault, un gestore di credenziali (Pannello di controllo \ Account utente e Family Safety \ Credential Manager) che memorizza i dati di accesso per una varietà di tipi di accesso, tra cui "credenziali generiche". Sulla superficie questo sembra il posto giusto per un programma per memorizzare le credenziali. Tuttavia, non ero in grado di trovare alcuna API per questo. Ho letto il riferimento Authentication function in MSDN, ma francamente ci siamo persi.

Esiste un'API in Windows Vault per archiviare e recuperare le credenziali da un programma e, in caso affermativo, dove è possibile trovare la documentazione?

+1

Sembra CredWrite(), CredRead(), ed altri nella sezione Funzioni Credenziali di gestione. – Luke

+1

Attualmente sto cercando soluzioni per l'archiviazione delle credenziali dell'utente: potresti dirmi perché hai deciso di passare dall'archiviazione del blob crittografato da CryptProtectData a Windows Vault? Più sicurezza? Sembra meno portabile alle precedenti versioni di Windows (ma al momento non sono sicuro che mi interessi). – BSchlinker

+0

Come BSchlinker, non capisco cosa ci stia guadagnando. In che modo è più sicuro dell'archiviazione sul filesystem? – Sammi

risposta

31

Mille grazie a @Luke per il suggerimento: le funzioni API di Windows per archiviare le credenziali e leggerle da Windows Vault sono CredWrite() e CredRead(). Ecco un esempio di codice che può essere compilato ed eseguito, che ho usato per confermare che queste funzioni davvero fare la cosa atteso:

#include <windows.h> 
#include <wincred.h> 
#include <tchar.h> 
#pragma hdrstop 

void main() 
{ 
    { //--- SAVE 
     char* password = "brillant"; 
     DWORD cbCreds = 1 + strlen(password); 

     CREDENTIALW cred = {0}; 
     cred.Type = CRED_TYPE_GENERIC; 
     cred.TargetName = L"FOO/account"; 
     cred.CredentialBlobSize = cbCreds; 
     cred.CredentialBlob = (LPBYTE) password; 
     cred.Persist = CRED_PERSIST_LOCAL_MACHINE; 
     cred.UserName = L"paula"; 

     BOOL ok = ::CredWriteW (&cred, 0); 
     wprintf (L"CredWrite() - errno %d\n", ok ? 0 : ::GetLastError()); 
     if (!ok) exit(1); 
    } 
    { //--- RETRIEVE 
     PCREDENTIALW pcred; 
     BOOL ok = ::CredReadW (L"FOO/account", CRED_TYPE_GENERIC, 0, &pcred); 
     wprintf (L"CredRead() - errno %d\n", ok ? 0 : ::GetLastError()); 
     if (!ok) exit(1); 
     wprintf (L"Read username = '%s', password='%S' (%d bytes)\n", 
       pcred->UserName, (char*)pcred->CredentialBlob, pcred->CredentialBlobSize); 
     // must free memory allocated by CredRead()! 
     ::CredFree (pcred); 
    } 
} 

Una credenziale generica viene memorizzato in Windows Vault, come si può vedere nello screenshot:

A generic credential stored in Windows Vault

+0

Esiste un modo per utilizzare le credenziali in un modo che non può essere recuperato? (come solo l'accesso a un URL). – eckes

7

Se qualcuno è interessato a leggere e scrivere ad esso da PowerShell o C#, ecco un link ad uno script che lo fa:

PowerShell Credentials Manager: CredMan.ps1

Lo script PowerShell accede all'API tramite inline C# che utilizza Pinvoke.

14

Per persone che unisce il filo in ritardo, v'è una nuova libreria di interagire con questo negozio in Windows 8 chiamato: Windows.Security.Credentials.PasswordVault

In realtà ci vogliono solo due linee di PowerShell per utilizzare la classe per visualizzare tutti i nomi utente e le password memorizzate sotto gli utenti correnti rappresentano:

[void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] 
(new-object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $_.RetrievePassword(); $_ } 
+0

@ClairelyClaire Sarebbe ancora attraverso credman. Quando visualizzo le credenziali di Windows Live tramite la GUI in win8.1, viene visualizzato come virtualapp/didlogical con un tipo di generico. Quindi se si enumerano i cred di tipo cred.Type = CRED_TYPE_GENERIC dovresti trovarne uno. [Link] (http://answers.microsoft.it/it-it/windows/forum/windows_7-security/unknown-credential-virtualappdidlogical/40467173-a75a-44b2-8617-5aa7a0479925) –

+0

Ho controllato i comandi per lo script di PowerShell pubblicato da Tim Lewis - non so come usare il sopra informazioni con quello. Riesco a vedere le credenziali memorizzate associate all'account MS collegato all'account utente di Windows 8: non esiste una password. – ClairelyClaire