Winforms アプリケーションにパスワードを保存するにはどうすればよいですか?
質問
winforms アプリに次のようなコードがあり、ユーザーのメールボックスのストレージ クォータをクエリするために作成していました。
DirectoryEntry mbstore = new DirectoryEntry(
@"LDAP://" + strhome,
m_serviceaccount,
[m_pwd],
AuthenticationTypes.Secure);
どのようなアプローチを試みたとしても(たとえば、 SecureString
)、パスワードを簡単に確認できます(m_pwd) リフレクターを使用するか、実行可能ファイルのプロセス エクスプローラーの文字列タブを使用します。
このコードをサーバーに配置したり、委任などのメカニズムを使用してセキュリティを強化したり、必要な権限のみをサービス アカウントに付与したりできることはわかっています。
ハッカーにパスワードを漏らすことなく、パスワードをローカル アプリケーションに保存する合理的に安全な方法を誰かが提案してくれませんか?
正確なパスワード(照合のためのハッシュだけでなく)を知る必要があるため、ハッシュ化は不可能です。暗号化/復号化メカニズムはマシンに依存しているため、機能しません。
解決
聖別された方法は、CryptoAPI とデータ保護 API を使用することです。
暗号化するには、次のようなものを使用します (C++)。
DATA_BLOB blobIn, blobOut;
blobIn.pbData=(BYTE*)data;
blobIn.cbData=wcslen(data)*sizeof(WCHAR);
CryptProtectData(&blobIn, description, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE | CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
_encrypted=blobOut.pbData;
_length=blobOut.cbData;
復号化はその逆です。
DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;
CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
std::wstring _decrypted;
_decrypted.assign((LPCWSTR)blobOut.pbData,(LPCWSTR)blobOut.pbData+blobOut.cbData/sizeof(WCHAR));
CRYPTPROTECT_LOCAL_MACHINE を指定しない場合、暗号化されたパスワードはレジストリまたは構成ファイルに安全に保存され、そのパスワードを復号化できるのは自分だけです。LOCAL_MACHINE を指定すると、マシンにアクセスできる人は誰でもそれを取得できます。
他のヒント
前述したように、データ保護 API はこれを行うための良い方法です。.NET 2.0 以降を使用している場合は、P/Invoke を使用して DPAPI を呼び出す必要はないことに注意してください。フレームワークは、呼び出しを System.Security.Cryptography.ProtectedData クラスでラップします。
私は、keith Brown 著の『Windows セキュリティに関する .NET 開発者ガイド』という本を見つけました。あらゆる種類のセキュリティ シナリオをカバーする優れたサンプルがいくつかあります。無料 オンライン版 も利用可能です。
それを安全な文字列として保存し、その安全な文字列をファイルに保存する場合 (おそらく使用します) 隔離されたストレージ, 、プレーン テキストのパスワードを取得できるのは、mbstore を作成するためにパスワードを復号化するときだけです。残念ながら、コンストラクターは SecureString または Credential オブジェクトを受け取りません。