Windows PCにプレーンテキストパスワードを安全に保存したい。現在、DPAPI CryptProtectData
を使用して暗号化し、暗号化されたblobをユーザーのローカルAppDataのファイルに保存しています。
Windows 7には、「一般的な資格情報」を含むさまざまなログオンタイプのログオンデータを格納する資格情報マネージャー(コントロールパネル\ユーザーアカウントおよび家族の安全\資格情報マネージャー)であるWindows Vaultがあります。表面上は、資格情報を保存するプログラムの適切な場所のように見えます。ただし、そのためのAPIを見つけることができませんでした。 MSDNで Authentication function referenceを読みましたが、率直に言って失われました。
プログラムから資格情報を保存および取得するためのWindows VaultへのAPIはありますか?はいの場合、ドキュメントはどこにありますか?
ヒントについて@Lukeに感謝します。WindowsVaultに資格情報を保存して読み取るためのWindows API関数は、 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 Vaultに保存されます。
スレッドに遅れて参加する人のために、Windows 8でこのストアと対話する新しいライブラリがあります:Windows.Security.Credentials.PasswordVault
実際、クラスを使用して現在のユーザーアカウントに保存されているすべてのユーザー名とパスワードを表示するには、2行のpowershellだけが必要です。
[void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
(new-object Windows.Security.Credentials.PasswordVault).RetrieveAll() | % { $_.RetrievePassword(); $_ }
Update: Windows 10ではMicrosoftが(ありがたいことに)このAPIをさらに制限し、すべてのパスワードをダンプしなくなったようですとても些細なことです。これは、私が見た変更を示しているだけです。
ロッカーの内容は、アプリまたはサービスに固有です。アプリとサービスは、他のアプリまたはサービスに関連付けられた資格情報にアクセスできません。
PowerShellまたはC#からの読み取りと書き込みに興味がある人は、それを行うスクリプトへのリンクを次に示します。
PowerShell Credentials Manager:CredMan.ps1
PowerShellスクリプトは、Pinvokeを利用するインラインC#を介してAPIにアクセスします。