(.NET) Простой способ генерировать случайные, легко запоминающиеся пароли
У меня есть проект в разработке, и мне нужно связать код доступа с элементом.
Пароль должен быть абсолютно непоследовательным или легко угадываемым, но простым для запоминания.
Я думал о том, чтобы сделать что-то подобное.
string rand = System.Guid.NewGuid().ToString();
rand.Substring(0,3);
Вернуть первые 4 цифры GUID.
Мне было интересно, есть ли у кого-то еще что-то подобное, над чем они работают, и потенциально лучшее решение, чем это.
Безопасность важна, так как мы не хотим, чтобы люди могли угадывать цифры, однако это не касается денег или личных данных, поэтому они не должны быть способными АНБ:)
Спасибо, парни!
7 ответов
Люди помнят слова лучше, чем они помнят коды...
Таким образом, простой способ состоит в том, чтобы сгенерировать фразу-пароль, а не тарабарское слово или код.
Самый простой способ сделать это - создать список из нескольких тысяч слов в базе данных или словаре, а затем случайным образом выбрать 3 или 4 из них.
Чем больше слов вы используете, тем сложнее будет угадать хакерам - 3 из 3 000 слов будут довольно неубедительными, а 4 из 20 000 слов будут иметь 1 600 000 000 000 000 000 комбинаций.
Если вы хотите что-то, что обеспечит ваших пользователей чем-то, что относительно легко запомнить, вы всегда можете использовать мой PronouncablePasswords
учебный класс.
Первоначально я написал это как эксперимент по генерации случайных паролей, которые можно было произносить конечному пользователю, а не как полный бред. Конечно, это снижает безопасность пароля, но для ваших целей кажется, что этого будет достаточно.
Функция просто чередуется между гласным и согласным (с некоторыми рудиментарными правилами исключений), с "взвешиванием" для выбранных букв на основании их появления в английском языке. Обратите внимание, что это ни в коем случае не идеально, но делает "то, что сказано на банке"!
Код:
using System;
using System.Collections.Generic;
using System.Text;
namespace PronouncablePasswords
{
class PasswordGenerator
{
//string vowels = "aeiou";
//string consonants = "bcdfghjklmnprstvwxyz";
/*
The reason for the duplicate letters is to add "weighting" to certain letters to allow them more chance
of being randomly selected. This is due to the fact that certain letters in the English language are more
frequently used than others.
The breakdown of usage is as follows (from most frequent to least frequent):
1. E (7)
2. T (6)
3. A, O, N, R, I, S (5)
4. H (4)
5. D, L, F, C, M, U (3)
6. G, Y, P, W, B (2)
7. V, K, X, J, Q, Z (1)
*/
string vowels = "aaaaaeeeeeeeiiiiiooooouuu";
string consonants = "bbcccdddfffgghhhhjklllmmmnnnnnpprrrrrsssssttttttvwwxyyz";
string[] vowelafter = {"th", "ch", "sh", "qu"};
string[] consonantafter = { "oo", "ee" };
Random rnd = new Random();
public string GeneratePassword(int length)
{
string pass = "";
bool isvowel = false;
for (int i = 0; i < length; i++)
{
if (isvowel)
{
if (rnd.Next(0, 5) == 0 && i<(length-1))
{
pass += consonantafter[rnd.Next(0, consonantafter.Length)];
}
else
{
pass += vowels.Substring(rnd.Next(0, vowels.Length), 1);
}
}
else
{
if (rnd.Next(0, 5) == 0 && i<(length-1))
{
pass += vowelafter[rnd.Next(0, vowelafter.Length)];
}
else
{
pass += consonants.Substring(rnd.Next(0, consonants.Length), 1);
}
}
isvowel = !isvowel;
}
return pass;
}
}
}
Если вы думаете о ПИН-коде, я бы предложил использовать все цифры (или, возможно, все буквы), а не первые четыре символа GUID. Многие люди знакомы с ПИН-кодами из всех цифр; Я подозреваю, что из-за того, что там написано письмо, им будет легче запомнить. Но у меня нет доказательств, подтверждающих это!
Если PIN-кода достаточно, вы можете просто позвонить в Random.Next(0, 9) четыре раза и объединить результаты. Обязательно исключайте "недостаточно случайные" результаты, например, когда все четыре цифры одинаковы! Как говорит неизвестный, вы можете получить статистически более случайные результаты от классов шифрования, но вряд ли это будет иметь значение из четырех цифр.
ASP .NET членство провайдера есть метод, который генерирует пароли, которые могут быть полезны. http://msdn.microsoft.com/en-us/library/system.web.security.membership.generatepassword.aspx также вы можете посмотреть на исходный код поставщиков, чтобы увидеть, что они делают внутри http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx
Какими характеристиками должен обладать ваш пароль? Если ваш основной критерий - запоминаемость, я бы предложил что-то вроде этого:
Найдите большой корпус английского текста и извлеките из него все уникальные слова из пяти или менее букв. Теперь для любого конкретного нового пароля случайным образом выберите три или четыре из этих слов. Затем в конце добавьте случайное двузначное число.
Сколько паролей? Ну, сотня за двузначное число, умноженное на (количество разных слов) до степени (количество случайных слов в пароле). Поэтому, если вы возьмете это из базы-двух, вы получите энтропию, которую вы могли бы иметь в этих паролях - если ваш генератор случайных чисел достаточно хорош.
На практике, если вы заблокируете учетные записи после нескольких попыток ввода неверного пароля, вы будете эффективно противодействовать злоумышленникам, если существует хотя бы несколько тысяч возможных паролей.
Я бы предложил использовать класс RandomNumberGenerator, он даст вам лучшие результаты, чем генерация GUID.