I want to securely store a plaintext password on Windows PC. I am currently using DPAPI CryptProtectData
to encrypt it, then store the encrypted blob in a file in user's local AppData.
In Windows 7, there is Windows Vault, a credential manager (Control Panel\User Accounts and Family Safety\Credential Manager) that stores logon data for a variety of logon types, including "generic credential". On the surface this looks like the right place for a program to store credentials. However, I was not able to find any API for it. I read Authentication function reference in MSDN, but frankly got lost in it.
Is there an API to Windows Vault to store and retrieve credentials from a program, and, if yes, where can I find documentation?
Many thanks to @Luke for the hint: Windows API functions to store credentials to and read them from Windows Vault are CredWrite()
and CredRead()
. Here is a code sample that may be compiled and run, that I used to confirm that these functions indeed do the expected thing:
#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);
}
}
A generic credential is stored in Windows Vault, as can be seen on the screenshot: