基本的なセキュリティ対策を講じてパスワードを保存するプロセスは非常に簡単です。
- パスワードをソルトでハッシュする
- ユーザー/パスワードごとに異なるソルトを使用する
- ハッシュされたパスワードを使用してソルトをDBに保存します
- ログインしようとしたときに、同じ方法で試行したPWを実行します。結果を比較します。
正しいパスワードを入力すると、ハッシュされたPWが一致します。ハッシュは、ユーザーを攻撃から保護するだけでなく、管理人がmembers
と一緒に画面を歩いていることからも保護します。 展示されているテーブル。
ソルトの作成とPWのハッシュ
' salt size is 32 (0-31
Private Const SaltSize As Integer = 31
...
Dim dbPW As String = TextBox1.Text
Dim dbSalt = CreateNewSalt(SaltSize)
' eg: "dsEGWpJpwfAOvdRZyUo9rA=="
Dim SaltedPWHash As String = GetSaltedHash(dbPW, dbSalt)
' examples:
' using SHA256: bbKN8wYYgoZmNaG3IsQ2DPS2ZPIOnenl6i5NwUmrGmo=
' using SHA512:
' 0vqZWBIbOlyzL25l9iWk51CxxJTiEM6QUZEH1ph+/aNp+lk4Yf8NYv8RLhYtbqCNpOqO3y8BmM+0YWtbAhE+RA=="
PWハッシュとソルトをユーザーのレコードの一部として保存します。ソルトは秘密ではありませんが、ユーザーがパスワードを変更したとき/変更した場合に変更してください。
ログイン試行の比較
' check if PW entered equals DB
Dim pwTry = TextBox2.Text
' hash the login attempt using the salt stored in the DB
Dim pwLogin = GetSaltedHash(pwTry, dbSalt)
' compare the hash of what they entered to whats in the DB:
If String.Compare(SaltedPWHash, pwLogin, False) = 0 Then
' okay!
Console.Beep()
End If
ユーザーが同じPWを入力すると、同じハッシュになるはずです。それはそれと同じくらい簡単です。ハッシュコードはそれほど複雑ではありません:
ハッシュメソッド
Private Function GetSaltedHash(pw As String, salt As String) As String
Dim tmp As String = pw & salt
' or SHA512Managed
Using hash As HashAlgorithm = New SHA256Managed()
' convert pw+salt to bytes:
Dim saltyPW = Encoding.UTF8.GetBytes(tmp)
' hash the pw+salt bytes:
Dim hBytes = hash.ComputeHash(saltyPW)
' return a B64 string so it can be saved as text
Return Convert.ToBase64String(hBytes)
End Using
End Function
Private Function CreateNewSalt(size As Integer) As String
' use the crypto random number generator to create
' a new random salt
Using rng As New RNGCryptoServiceProvider
' dont allow very small salt
Dim data(If(size < 7, 7, size)) As Byte
' fill the array
rng.GetBytes(data)
' convert to B64 for saving as text
Return Convert.ToBase64String(data)
End Using
End Function
- GUID(
System.Guid.NewGuid.ToString
)のようなものを使用したくなります )塩としてですが、暗号化乱数ジェネレーターを使用するのはそれほど難しいことではありません。 - ハッシュされたパスワードと同様に、エンコードのために返される文字列は長くなります。
- ユーザーがパスワードを変更するたびに、新しいソルトを作成します。グローバルソルトを使用しないでください。目的が損なわれます。
- PWを複数回ハッシュすることもできます。重要なのは、攻撃された場合にさまざまな組み合わせをすべて試すのに長い時間をかけることです。
- 関数は
Shared
の理想的な候補です /static
クラスのメンバー。
また、ケネス によってリンクされている記事にも注意してください 読む価値は十分にあります。
記事
に注意してください 言及The salt should be stored in the user account table alongside the hash
これは、Salt
が必要だという意味ではありません DBの列。リンク先の記事で次のことが行われていることがわかります。
Dim dbPW As String = TextBox1.Text
Dim dbSalt = CreateNewSalt(SaltSize)
' get the salted PW hash
Dim SaltedPWHash As String = GetSaltedHash(dbPW, dbSalt)
' store salt with the hash:
SaltedPWHash = String.Format("{0}:{1}", dbSalt, dbPW)
' salt + ":" + hashed PW now ready to store in the db
ハッシュされたパスワードからソルトを分割するには:
Dim SaltAndPWHash = rdr.Item("PWHash").ToString()
Dim split = SaltAndPWHash.Split(":"c) ' split on ":"
Dim Salt = split(0) ' element(0) == salt
Dim StoredPWHash = split(1) ' element(1) == hashed PW
両方の部分が必要です。PWで試行されたログをハッシュした後、それをsplit(1)
と比較します。 。