現在、ユーザーのログイン資格情報がSQLServerDBに保存されているアプリケーションがあります。これらは、基本的に、プレーンテキストのユーザー名、パスワードハッシュ、およびこのハッシュに関連付けられたソルトとして保存されます。
これらはすべて、ASP.NETのメンバーシップ/ロールシステムに組み込まれている関数によって作成されました。'joe'という名前のユーザーと'password'のパスワードの行は次のとおりです。
joe、kDP0Py2QwEdJYtUX9cJABg ==、OJF6H4KdxFLgLu + oTDNFodCEfMA =
このようなものをCSVファイルにダンプし、パスワードを次の形式で保存するDjangoで使用可能な形式にしようとしています。
[algo] $ [salt] $ [hash]
ここで、saltはプレーンな文字列であり、ハッシュはSHA1ハッシュの16進ダイジェストです。
これまでのところ、ASPがこれらのハッシュとソルトをbase64形式で保存していることを確認できました。上記の値は、バイナリ文字列にデコードされます。
リフレクターを使用して、ASPがこれらの値に対してどのように認証するかを収集しました。
internal string EncodePassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0)
{
return pass;
}
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] src = Convert.FromBase64String(salt);
byte[] dst = new byte[src.Length + bytes.Length];
byte[] inArray = null;
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
if (passwordFormat == 1)
{
HashAlgorithm algorithm = HashAlgorithm.Create(Membership.HashAlgorithmType);
if ((algorithm == null) && Membership.IsHashAlgorithmFromMembershipConfig)
{
RuntimeConfig.GetAppConfig().Membership.ThrowHashAlgorithmException();
}
inArray = algorithm.ComputeHash(dst);
}
else
{
inArray = this.EncryptPassword(dst);
}
return Convert.ToBase64String(inArray);
}
基本的に、DBからソルトをプルし、b64はそれをバイナリ表現にデコードします。生のパスワードに対して「GetBytes」を実行し、次にそれらを連結します。最初にソルトします。
次に、この新しい文字列に対してSHA1アルゴリズムを実行し、base64でエンコードして、データベースに保存されている値と比較します。
Pythonでこれらのハッシュを再現するためのコードを作成しようとしましたが、失敗しました。これがどのように変換されるかを理解できるまで、Djangoでそれらを使用することはできません。これが私がテストしている方法です:
import hashlib
from base64 import b64decode, b64encode
b64salt = "kDP0Py2QwEdJYtUX9cJABg=="
b64hash = "OJF6H4KdxFLgLu+oTDNFodCEfMA="
binsalt = b64decode(b64salt)
password_string = 'password'
m1 = hashlib.sha1()
# Pass in salt
m1.update(binsalt)
# Pass in password
m1.update(password_string)
# B64 encode the binary digest
if b64encode(m1.digest()) == b64hash:
print "Logged in!"
else:
print "Didn't match"
print b64hash
print b64encode(m1.digest())
誰かが私のアプローチの欠陥を見ることができるか、または別の方法を提案できるかどうか疑問に思っています。おそらく、上記のアルゴリズムと上記の既知のパスワードとソルトを使用して、システムでハッシュを生成できますか?