У нас есть текущее приложение, в котором учетные данные пользователя хранятся в БД SQL Server. Они, как правило, хранятся в виде обычного текстового имени пользователя, хэша пароля и связанной соли для этого хеша.
Все они были созданы встроенными функциями в системе членства / роли ASP.NET. Вот строка для пользователя с именем 'joe' и паролем 'password':
джо, kDP0Py2QwEdJYtUX9cJABg ==, OJF6H4KdxFLgLu + oTDNFodCEfMA =
Я выбросил этот материал в CSV-файл и пытаюсь перевести его в удобный для Django формат, который хранит свои пароли в следующем формате:
[алго] $ [соль] $ [хеш]
Если соль - простая строка, а хеш - это шестнадцатеричный дайджест хеша SHA1.
До сих пор мне удавалось установить, что 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);
}
В сущности, извлекает соль из БД, а 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())
Мне интересно, может ли кто-нибудь увидеть какие-либо недостатки в моем подходе или может предложить альтернативный метод. Возможно, вы можете воспользоваться приведенными выше алгоритмами, а также известным паролем и солью и создать хеш в своей системе?