ASP.NET членская соль?
Как членство ASP.NET генерирует свой ключ соли, а затем как они кодируют его (то есть, это соль + пароль или пароль + соль)?
Я использую SHA-1 с моим членством, но я хотел бы воссоздать те же соли, чтобы встроенный элемент принадлежности мог хешировать вещи так же, как мои вещи могут.
Изменить 2: Ничего. Я неправильно понял и думал, что он сказал байты, а не бит. Таким образом, я проходил 128 байтов, а не 128 бит.
Изменить: Я пытался это сделать. Это то, что у меня есть,
public string EncodePassword(string password, string salt)
{
byte[] bytes = Encoding.Unicode.GetBytes(password);
byte[] src = Encoding.Unicode.GetBytes(salt);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
private byte[] createSalt(byte[] saltSize)
{
byte[] saltBytes = saltSize;
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
return saltBytes;
}
Итак, я не пытался узнать, узнает ли членство ASP.NET, но хешированный пароль выглядит близко. Я просто не знаю, как преобразовать его в base64 для соли.
Я сделал это
byte[] storeSalt = createSalt(new byte[128]);
string salt = Encoding.Unicode.GetString(storeSalt);
string base64Salt = Convert.ToBase64String(storeSalt);
int test = base64Salt.Length;
Длина теста равна 172, что намного превышает 128 бит, так что я делаю неправильно?
Это их соль выглядит как
vkNj4EvbEPbk1HHW+K8y/A==
Это то, что моя соль выглядит как
E9oEtqo0livLke9+csUkf2AOLzFsOvhkB/NocSQm33aySyNOphplx9yH2bgsHoEeR/aw/pMe4SkeDvNVfnemoB4PDNRUB9drFhzXOW5jypF9NQmBZaJDvJ+uK3mPXsWkEcxANn9mdRzYCEYCaVhgAZ5oQRnnT721mbFKpfc4kpI=
Ответы
Ответ 1
Что такое хэш-алгоритм по умолчанию, который использует членство ASP.NET? имеет хорошее обсуждение их алгоритма по умолчанию.
Я надеюсь, что это поможет!
Edit-
Ответ, на который я имел в виду, - это код в верхнем сообщении,
public string EncodePassword(string pass, string salt)
{
byte[] bytes = Encoding.Unicode.GetBytes(pass);
//byte[] src = Encoding.Unicode.GetBytes(salt); Corrected 5/15/2013
byte[] src = Convert.FromBase64String(salt);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
Они объединяют Unicode Salt + Pass, используя BlockCopy
- В ответ на ваш вопрос:
Оба алгоритма необходимы и выполняют разные роли...
RNG Crypto используется для получения соли. Это в основном длинная строка случайных данных. Это генерируется и сохраняется на основе каждого пользователя. Обычно это делается при создании пользователя или изменении пароля.
BlockCopy - это просто метод, который они используют для объединения соли с паролем. Вышеприведенный код по существу означает соль + пароль.
Вы не сможете воссоздать значение соли, поскольку оно абсолютно случайное. Тем не менее, он хранится для каждого пользователя в рамках.
Объединяя соль с паролем и хешируя его с помощью вышеприведенной техники, вы сможете проверять пароли пользователей, используя хешированное значение, хранящееся в структуре.
Я думаю, что мы оба по-другому читаем ваш вопрос. Код, который я написал, не будет генерировать соль, но он позволит вам использовать его таким образом, который совместим с членством в ASP.NET.
Извините, мое объяснение не самое лучшее - это ответ на ваш вопрос?
Ответ 2
Вот как SQLMembershipProvider генерирует соль.
private string GenerateSalt() {
var buf = new byte[16];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}
Вы можете загрузить код поставщика ASP.NET SQL здесь.
Проблема, с которой я столкнулась, - это приложение для разработки, работающее на IIS7. В .NET 4.0 использовался другой хэш-алгоритм по умолчанию, отличный от HashAlgorithmType по умолчанию для .NET 2.0.
В примере кода "EncodePassword" от Microsoft они ссылаются на Membership.HashAlgorithmType
, который, как мне кажется, возвращает значение по умолчанию для фреймворка, если оно не указано в web.config
.
Мне удалось заставить оба метода GenerateSalt и EncodePassword работать для моего приложения.
Мой комбинированный код:
internal string GenerateSalt()
{
byte[] buf = new byte[16];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}
internal string EncodePassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0) // MembershipPasswordFormat.Clear
return pass;
byte[] bIn = Encoding.Unicode.GetBytes(pass);
byte[] bSalt = Convert.FromBase64String(salt);
byte[] bAll = new byte[bSalt.Length + bIn.Length];
byte[] bRet = null;
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
if (passwordFormat == 1)
{ // MembershipPasswordFormat.Hashed
HashAlgorithm s = HashAlgorithm.Create("SHA1");
// Hardcoded "SHA1" instead of Membership.HashAlgorithmType
bRet = s.ComputeHash(bAll);
}
else
{
bRet = EncryptPassword(bAll);
}
return Convert.ToBase64String(bRet);
}
Ответ 3
Вот один из способов сделать это. Соль - это просто случайное число, вы можете использовать класс RNGCryptoServiceProvider в библиотеке фреймов для получения хорошего случайного числа для использования в качестве соли
private const int ITERATIONS = 10000;
private const int SALT_SIZE = 32;
private const int HASH_SIZE = 32;
public void SaltAndHashPassword(string password, out byte[] salt,
out byte[] hash)
{
Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(
password,
SALT_SIZE,
ITERATIONS);
salt = rdb.Salt;
hash = rdb.GetBytes(HASH_SIZE);
}