Как хранить и получать учетные данные из диспетчера учетных данных Windows Vault? - PullRequest
32 голосов
/ 10 февраля 2012

Я хочу надежно хранить незашифрованный пароль на ПК с Windows. В настоящее время я использую DPAPI CryptProtectData для его шифрования, а затем сохраняю зашифрованный большой двоичный объект в файле в локальных пользовательских данных AppData.

В Windows 7 имеется Windows Vault, диспетчер учетных данных (Панель управления \ Учетные записи пользователей и Семейная безопасность \ Диспетчер учетных данных), в котором хранятся данные для входа в систему для различных типов входа, включая «общие учетные данные». На первый взгляд это выглядит как правильное место для программы для хранения учетных данных. Однако я не смог найти API для этого. Я прочитал Ссылка на функцию аутентификации в MSDN, но, честно говоря, потерялся в ней.

Существует ли API для Windows Vault для хранения и получения учетных данных из программы, и, если да, где я могу найти документацию?

Ответы [ 3 ]

33 голосов
/ 10 февраля 2012

Большое спасибо @Luke за подсказку: функции Windows API для хранения учетных данных и их чтения из хранилища Windows: CredWrite() и CredRead(). Вот пример кода, который может быть скомпилирован и запущен, который я использовал для подтверждения того, что эти функции действительно выполняют ожидаемые действия:

#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);
    }
}

Общие учетные данные хранятся в хранилище Windows, как показано на скриншоте:

A generic credential stored in Windows Vault

15 голосов
/ 20 декабря 2013

Для тех, кто поздно присоединяется к потоку, в Windows 8 есть новая библиотека для взаимодействия с этим хранилищем, которая называется: Windows.Security.Credentials.PasswordVault

Фактически, для использования класса для просмотра всех классов требуется всего две строки powershellимена пользователей и пароли, хранящиеся под текущей учетной записью пользователя:

[void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
(new-object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $_.RetrievePassword(); $_ }
7 голосов
/ 29 августа 2013

Если кому-то интересно читать и писать в него из PowerShell или C #, вот ссылка на скрипт, который это делает:

Диспетчер учетных данных PowerShell: CredMan.ps1

Сценарий PowerShell обращается к API через встроенный C #, который использует Pinvoke.

...