ログインフォームを備えたWinFormsアプリケーションがあり、暗号化されたユーザー名とパスワードをSQLiteデータベースに保存したいと考えています。ソルトとハッシュを使用できることはわかりましたが、コードでパスワードを暗号化して、認証時に比較する方法がわかりません。
何か助けてください?
ログインフォームを備えたWinFormsアプリケーションがあり、暗号化されたユーザー名とパスワードをSQLiteデータベースに保存したいと考えています。ソルトとハッシュを使用できることはわかりましたが、コードでパスワードを暗号化して、認証時に比較する方法がわかりません。
何か助けてください?
ユーザー名とパスワード(マスクされたテキストボックスからのパスワード、できれば確認用の2番目のボックスを含む)を取得し、パスワードからハッシュを作成してから、パスワードのプレーンテキストのユーザー名とソルトされたハッシュをに挿入する必要があります。データベースに。その後、データベースに保存されているバージョンを、ユーザーが入力したもののソルト(同じソルト!)ハッシュと比較することで、ユーザーのパスワードを将来確認できます。
各ユーザーは、アカウントを作成するときにそのユーザー用にランダムに生成する独自のソルトを持っている必要があることに注意してください。(これは、ハッカーが発見できるグローバルなソルト値よりも安全です)。
この記事を見てください。ほぼすべてのベースをカバーしていますが、記事で推奨されているようにSHA-1を使用しないでください。BCryptやPBKDF2(.NETに含まれている)など、計算コストの高い低速ハッシュ関数が必要です。「パスワードの優れたハッシュ関数とは」を参照してください。(これを指摘してくれた@CodeInChaosに感謝します)。
System.Security.CryptographyのRfc2898DeriveBytesを使用して、パスワードのソルトハッシュPBKDF2スタイルを作成できます。
byte[] salt = Guid.NewGuid().ToByteArray[];
Rfc2898DeriveBytes saltedHash = new Rfc2898DeriveBytes("P@$$w0rd", salt, 1000);
経験則として、反復回数によってハッシュ操作に約1秒かかるはずです。
ハッシュ化されたパスワードとソルトをデータベースに保存する必要があります。ユーザーごとにランダムなソルトを使用します(GUIDで十分です)次のような方法でパスワードをハッシュできます。
using System.Security.Cryptography;
名前空間を追加することを忘れないでください。
public static string ComputeHash(string passwordPlainText, string saltString)
{
// Convert plain text into a byte array.
byte[] saltBytes = Encoding.UTF8.GetBytes(saltString);
// Convert plain text into a byte array.
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
// Allocate array, which will hold plain text and salt.
byte[] plainTextWithSaltBytes =
new byte[plainTextBytes.Length + saltBytes.Length];
// Copy plain text bytes into resulting array.
for (int i = 0; i < plainTextBytes.Length; i++)
plainTextWithSaltBytes[i] = plainTextBytes[i];
// Append salt bytes to the resulting array.
for (int i = 0; i < saltBytes.Length; i++)
plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
// Because we support multiple hashing algorithms, we must define
// hash object as a common (abstract) base class. We will specify the
// actual hashing algorithm class later during object creation.
HashAlgorithm hash;
hash = new SHA256Managed();
// Compute hash value of our plain text with appended salt.
byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
// Create array which will hold hash and original salt bytes.
byte[] hashWithSaltBytes = new byte[hashBytes.Length +
saltBytes.Length];
// Copy hash bytes into resulting array.
for (int i = 0; i < hashBytes.Length; i++)
hashWithSaltBytes[i] = hashBytes[i];
// Append salt bytes to the result.
for (int i = 0; i < saltBytes.Length; i++)
hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];
// Convert result into a base64-encoded string.
string hashValue = Convert.ToBase64String(hashWithSaltBytes);
// Return the result.
return hashValue;
}
SHA256Managed
サポートされている他のハッシュアルゴリズムに変更できます。
更新:最初に概念を理解する必要があると思います。私はそれを説明しようとします:
ログインする前に、データベースにユーザーを作成する必要があります。それらを作成するには、ユーザー名とパスワードが必要です。
Guid.NewGuid().ToString();
たとえば、ランダムなSALTを生成します。string ComputeHash(string passwordPlainText, string saltString)
(このステップは、以前に投稿した関数を使用して実行できます。