Как сохранить и получить учетные данные из диспетчера учетных данных Windows Vault?

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

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

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


person kkm    schedule 10.02.2012    source источник
comment
Похоже на CredWrite (), CredRead () и др. В разделе Функции управления учетными данными.   -  person Luke    schedule 10.02.2012
comment
В настоящее время я ищу решения для хранения учетных данных пользователя. Не могли бы вы сказать мне, почему вы решили переключиться с хранения зашифрованного большого двоичного объекта с CryptProtectData на Windows Vault? Больше безопасности? Он кажется менее переносимым для предыдущих версий Windows (но на данный момент я не уверен, что мне это будет интересно).   -  person BSchlinker    schedule 26.03.2012
comment
Как и BSchlinker, я не понимаю, что это нам дает. Чем это безопаснее, чем хранение в файловой системе?   -  person Sammi    schedule 06.09.2016
comment
@Sammi: Нет никаких указаний на то, что этот метод более / менее безопасен, чем любой другой. Я не думаю, что это на самом деле более безопасно в каком-либо смысле, но я не могу сказать вам наверняка, извините.   -  person kkm    schedule 06.09.2016
comment
@kkm Просто кажется бессмысленным, вот о чем я думал. Боль без выгоды. Но я не знаю. Кроме того, он привязывает вас к Windows, что, к сожалению, в наши дни славы кроссплатформенного ядра .NET.   -  person Sammi    schedule 07.09.2016
comment
stackoverflow .com / questions / 17741424 /   -  person Ohad Schneider    schedule 20.12.2016


Ответы (3)


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

#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 Vault, как видно на снимке экрана:

Общие учетные данные, хранящиеся в Windows Vault

person kkm    schedule 10.02.2012
comment
Есть ли способ использовать учетные данные таким образом, чтобы их нельзя было получить? (например, только вход в URL-адрес). - person eckes; 31.08.2016

Для тех, кто присоединяется к потоку поздно, есть новая библиотека для взаимодействия с этим магазином в 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(); $_ }

Обновление: похоже, что Microsoft (к счастью) ограничила этот API больше в Windows 10, и он больше не будет сбрасывать все ваши пароли так тривиально. Это только указание на изменение, которое я видел:

Содержимое шкафчика зависит от приложения или службы. Приложения и службы не имеют доступа к учетным данным, связанным с другими приложениями или службами.

person Tim    schedule 20.12.2013
comment
@ClairelyClaire Это все равно будет через кредитора. Когда я просматриваю свои учетные данные Windows Live через графический интерфейс в win8.1, они отображаются как virtualapp / didlogical с типом generic. Итак, если вы перечисляете кредиты типа cred.Type = CRED_TYPE_GENERIC, вы должны его найти. ссылка - person Tim; 29.07.2014
comment
Я просмотрел команды для сценария PowerShell, который опубликовал Тим Льюис - не знаю, как использовать с этим приведенную выше информацию. Я вижу сохраненные учетные данные, связанные с учетной записью MS, подключенной к учетной записи пользователя Windows 8 - там просто нет пароля. - person ClairelyClaire; 03.08.2014
comment
Невозможно следовать этому утверждению, поскольку все пароли, записанные в хранилище паролей Win10 с помощью TYPE_GENERIC, могут быть прочитаны также другими приложениями. В stackoverflow.com/questions/33754249/ Включен образец, который печатает пароли от нескольких приложений. Только пароли домена недоступны (или не так просто) доступны, а пароли WindowsLive и MicrosoftAccount также недоступны (когда я пытался, CredEnumerate вернул ошибку) - person Christoph Bimminger; 15.08.2020

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

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

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

person Tim Lewis    schedule 29.08.2013