いわゆる「レインボーテーブル」を使用したリバースエンジニアリングの対象となる可能性がある、「ソルト化されていない」パスワードハッシュをデータベースに保存することの危険性について説明しているこの記事に出くわしました。
また、この C# コード サンプルも付属しています。このC# コード サンプルでは、ユーザー パスワード データベース テーブルに 2 つのハッシュ列を格納する必要があります (従来の 1 つではなく)。ハッシュ、および新しい列を追加するには、データベースの再構築が必要になります。そのため、それを行う前に、別の代替案を探していましたが、ここに思いつきました。
パスワードの SHA1 ハッシュを単純に計算する代わりに、疑似乱数 (ただし一貫性のある) データの長いシーケンスをパディングしてからハッシュを計算する関数を次に示します。
byte[] computeSecureHash(string strUserPassword)
{
//RETURN: = SHA1 byte array on the 'strUserPassword'
//Make simple junk array based on the password
ushort v = 117;
byte[] arrJunk = new byte[24];
for (int c = 0, i = 0; i < arrJunk.Length; i++)
{
v ^= strUserPassword[c++];
v *= 7;
arrJunk[i] = (byte)v;
if (c >= strUserPassword.Length)
c = 0;
}
//Make crypto byte array based on the password
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(strUserPassword, arrJunk);
pbkdf2.IterationCount = 1000;
byte[] arrCrypto = pbkdf2.GetBytes(128);
//Pad actual password
string strUserPassword_Padded = "";
const string strChars2Use = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`-=[]\\;',./~!@#$%^&*()_+{}|:\"<>?";
int nHalfArrCrypto = arrCrypto.Length / 2;
//Left side
for (int i = 0; i < nHalfArrCrypto; i++)
{
strUserPassword_Padded += strChars2Use[arrCrypto[i] % strChars2Use.Length];
}
strUserPassword_Padded += strUserPassword;
//Right side
for (int i = nHalfArrCrypto; i < arrCrypto.Length; i++)
{
strUserPassword_Padded += strChars2Use[arrCrypto[i] % strChars2Use.Length];
}
//For user's password "123"
//the 'strUserPassword_Padded' becomes:
//"bwDR]_B>H5t-k:eIq?r_wGBWqWfs#tcAE~DQ5?(Pbj#<+Cw:9(r!B[f_.S<pCjn-123b9l3<Sz^D~>G}v)?NuHT4BZ-pI2$W[kW1e4KO\"`rTg3H`}&jmtrFh1J5c72:})tQ"
//And now compuse SHA1 on the padded password
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] bytesInputData = System.Text.Encoding.UTF8.GetBytes(strUserPassword_Padded);
return sha1.ComputeHash(bytesInputData);
}
だから私の質問は、誰かがこのコードを見直して、この方法でそれを行うことの危険性と、作者が彼のコードで提案したことの危険性を教えてもらえますか? 私のコード サンプルの場合、データベースには 2 つのハッシュ (パスワード ハッシュ + ソルト ハッシュ) ではなく 1 つのハッシュのみを格納する必要があります。