Windows Vista includes a new function to prompt for user credentials, CredUIPromptForWindowsCredentials. Rather than using CredUIPromptForCredentials, you should use the new function because the credential is encrypted by the operating system and can be unpacked by the application when needed without the application having access to the encryption key.
In short, credentials are always encrypted until needed. The following code is an example of how to use the API:
CREDUI_INFO ci = {0}; ULONG ulAuthPkg = 0; void *pAuthBuff = NULL; ULONG cbAuthBuff = 0; void *pOutAuthBuff = NULL; ULONG cbOutAuthBuff = 0; BOOL fSave = FALSE; DWORD dwFlags = CREDUIWIN_CHECKBOX; ci.cbSize = sizeof ci; ci.hbmBanner = NULL; ci.hwndParent = NULL; ci.pszCaptionText = L"Writing Secure Code for Windows Vista"; ci.pszMessageText = L"Please enter your password"; DWORD dwErr = CredUIPromptForWindowsCredentials( &ci, 0, &ulAuthPkg, pAuthBuff, cbAuthBuff, &pOutAuthBuff, &cbOutAuthBuff, &fSave, dwFlags); if (dwErr != 0) { wprintf(L"CredUI failed, err = %d\n",dwErr); return dwErr; } WCHAR wszUsername[CREDUI_MAX_USERNAME_LENGTH + 1]; DWORD cchUsername = _countof(wszUsername); WCHAR wszPassword[CREDUI_MAX_PASSWORD_LENGTH + 1]; DWORD cchPassword = _countof(wszPassword); WCHAR wszDomain[CRED_MAX_DOMAIN_TARGET_NAME_LENGTH + 1]; DWORD cchDomain = 0; // Attempt to decrypt the user's password BOOL fOK = CredUnPackAuthenticationBuffer( CRED_PACK_PROTECTED_CREDENTIALS, pOutAuthBuff, cbOutAuthBuff, wszUsername, &cchUsername, wszDomain, &cchDomain, wszPassword, &cchPassword); if (!fOK) { wprintf(L"Unpack failed, err = %d\n",GetLastError()); } else { // Use the creds SecureZeroMemory(wszPassword); } if (pOutAuthBuff) { SecureZeroMemory(pOutAuthBuff,cbOutAuthBuff); CoTaskMemFree(pOutAuthBuff); pOutAuthBuff = NULL; }
The most important reason to use this function over the older credential user interface API is the ability to display the credential dialog on the Windows logon desktop, therefore reducing the chance an attacker can spoof the dialog and steal a user’s credentials. You can enable this setting in Group Policy by navigating to Computer Configuration | Administrative Templates | Windows Components | Credential User Interface, and then enable “Require trusted path for credential entry.” From now on, when an application calls CredUIPromptForWindowsCredentials she will see the series of dialogs shown in Figures 9-1 and 9-2.
Figure 9-1: First stage of CredUI prompting for user credentials on the Windows logon desktop.
Figure 9-2: Second stage of CredUI prompting for user credentials on the Windows logon desktop.
Once the user presses Ctrl-Alt-Del, the credential dialog appears on the Windows logon desktop.