2012-09-30 23 views
72

私は最初にログインする必要があるWindowsアプリケーションを作っています。
アカウントの詳細はユーザー名とパスワードで構成され、ローカルに保存する必要があります。
セキュリティの問題であるため、同じコンピュータを使用している他の人は誰の個人データも見ることができません。
このデータを保存する最も安全な方法は何ですか? ユーザー名/パスワード(ローカル)を安全に保存する方法は?

私は、データベースを使用したくないので、私はリソースファイルでいくつかのことを試してみました。
しかし、私はこれで新しいことをしているので、私は何をやっているのか、どこで解決策を探しているのかは完全に分かっていません。

+4

まずパスワードを保存しないでください。それをハッシュし(おそらく塩の値で)、それを代わりに保存します。 – carlosfigueira

+0

「ユーザー」とは、通常のWindowsユーザーを意味しますか? (普通のWindowsユーザーは既にお互いのデータを見ることができないので、あなたのうちの何人かが「ユーザー」を所有していると思います) –

+0

私はあなたのタイトルを編集しました。 「[質問には「タイトル内に「タグ」を含める必要がありますか」(http://meta.stackexchange.com/questions/19190/)」を参照してください。コンセンサスは「いいえ、そうすべきではありません」です。 –

答えて

120

入力されたユーザー名とパスワードを検証/検証する場合は、Rfc2898DerivedBytesクラス(パスワードベースのキー導出関数2またはPBKDF2)を使用します。これは、トリプルDESやAESなどの暗号化を使用するよりも安全です。なぜなら、RFC2898DerivedBytesの結果からパスワードに戻る実際的な方法がないからです。あなたはパスワードから結果に行くことができます。 .Netの例と説明、またはWinRT/Metroの場合のString encrypt/decrypt with password c# Metro Styleについては、Is it ok to use SHA1 hash of password as a salt when deriving encryption key and IV from password string?を参照してください。

パスワードを第三者に提供するなど、再使用のために保管する場合は、Windows Data Protection API (DPAPI)を使用してください。これは、オペレーティングシステムで生成され保護された鍵とTriple DES暗号化アルゴリズムを使用して情報を暗号化および復号化します。つまり、アプリケーションでは、暗号化キーを生成して保護することを心配する必要がなく、暗号化を使用する際の大きな問題となります。

C#では、System.Security.Cryptography.ProtectedDataクラスを使用します。例えば、データの一部を暗号化するために、ProtectedData.Protect()を使用:

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes(). 
byte[] plaintext; 

// Generate additional entropy (will be used as the Initialization vector) 
byte[] entropy = new byte[20]; 
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
{ 
    rng.GetBytes(entropy); 
} 

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy, 
    DataProtectionScope.CurrentUser); 

ストアエントロピー及びそのようなので、現在のユーザーのみがそれを読むことができます設定されたアクセス権を持つファイルやレジストリキーのように確実に暗号文、。元のデータへのアクセスを取得するには、ProtectedData.Unprotect()を使用します。

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy, 
    DataProtectionScope.CurrentUser); 

注追加のセキュリティ上の考慮事項があること。たとえば、パスワードのような機密情報をstringとして保存しないでください。文字列は不変です。メモリに通知できないため、アプリケーションのメモリやメモリダンプを見ているユーザーがパスワードを参照することがあります。代わりにSecureStringまたはバイト[]を使用し、パスワードが不要になったらすぐに破棄してください。

+0

こんにちは、これを試しましたが、エントロピー= rng.GetBytes(20)でエラーが発生しました。intからbyte []に​​変換できません。 – Robin

+0

@CrispyGMR答えの中にそのコードを修正しました。良いキャッチ。 – akton

+0

ありがとうございました。最初はハッシュのためにmd5を使用しましたが、私はそれについて懐疑的でした。これはより安全な方法です。しかしもう1つの質問。私はこのようなかなりのデータをテキストファイルに保存したいと思います。ファイルを開いたときにランダムな文字列が表示されますが、これを行うには十分安全ですか?または、データを格納する別の方法をお勧めしますか? – Robin

6

私は前にこれを使用していると私は存続を必ず資格を作るために考え、最善の安全な方法で

  1. はあなたがConfigurationManagerクラス
  2. を使用して、アプリケーションの設定ファイルに書き込むことができますですSecureStringクラス
  3. を使用してパスワードを確保し、次にCryptography名前空間のツールを使用してパスワードを暗号化します。

このリンクをクリックすると、大きな助けになるだろう、私は願っています:Click here

3

DPAPIは、この目的のためだけです。 DPAPIを使用して、ユーザーが最初に入力するときにパスワードを暗号化し、安全な場所(ユーザーのレジストリ、ユーザーのアプリケーションデータディレクトリ、いくつかの選択肢)に保存します。アプリが起動されるたびに、あなたのキーが存在するかどうか、DPAPIを使ってそれを解読してアクセスを許可するかどうか、そうでなければそれを拒否するかどうかを確認するために、場所を確認してください。

関連する問題