Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
TW>Нужно чтобы между символами и паролями не было математической зависимости
TW>То есть rand(), rand(), rand(), rand() не подходит
TW>Единственное, что мне пришло в голову rand(GetTickCount()) TW>Но этого мало. А дальше то как?
Здравствуйте, TailWind, Вы писали:
TW>Нужно чтобы между символами и паролями не было математической зависимости
TW>То есть rand(), rand(), rand(), rand() не подходит
Не специалист, но слышал о том, что копать нужно в сторону CSPRNG. По этой ссылке в Wikipedia есть названия конкретных реализаций, вроде CryptGenRandom для Windows или /dev/urandom для Linux.
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
TW>Нужно чтобы между символами и паролями не было математической зависимости
вроде стандартный подход: попросить у пользователя случайную последовательность (мышкой поводить, набрать абракадабру на клавиатуре). И её уже использовать как затравку для rand.
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
TW>Нужно чтобы между символами и паролями не было математической зависимости
Когда говоришь о "случайных значениях", надо в первую очередь определить, требуется ли максимально непредсказуемая случайность, или нужно таки получить воспроизводимость.
Раз речь о паролях — то скорее первое.
Тогда второе это какая платформа.
В современных Unix типа Linux, MacOS самый простой и надёжный вариант это открыть /dev/urandom, прочитать нужное количество байт из него (они будут равномерно распределёнными значениями от 0 до 255, независимые друг от друга) и из них сгенерировать что нужно.
Для винды мне подсказывают про CryptGetRandom(), но я не проверял.
TW>То есть rand(), rand(), rand(), rand() не подходит
TW>Единственное, что мне пришло в голову rand(GetTickCount()) TW>Но этого мало. А дальше то как?
И какой набор символов?
Вот что-то вроде подобного я бы сделал для Linux
SP>вроде стандартный подход: попросить у пользователя случайную последовательность (мышкой поводить, набрать абракадабру на клавиатуре). И её уже использовать как затравку для rand.
Не очень понятно как из этого сделать равномерное распределение
Проблема с rand() в том, что она повторяется каждые 3fff байт
Имея на руках программу можно сгенерировать всего 3fff комбинаций пароля.
А это перебором можно подобрать
Здравствуйте, so5team, Вы писали:
N>>Топорно (целых 8 байт входа на один символ выхода) но работает. S>А разве /dev/urandom нельзя читать побайтово?
Можно, но если, например, 36 символов возможно в пароле (26 английских букв и 10 цифр), а мы берём по 1 байту входа на символ выхода... 256 делим на 36, в остатке 4 — это значит, что первые 4 в наборе будут генерироваться чаще, чем остальные (на 1/7 чаще).
Эффект не сильно большой, но для серьёзной секьюрити может влиять.
Если больше набор (до 70 символов можно позволить), эффект ещё сильнее, типа 1/3 разницы.
А если делить на входе числа от 0 до 2**64-1, эффект становится неизмеримо малым.
Это то, почему std::hash()() должен выдавать size_t (я удивлён, что не uintmax_t, но, видимо, сочли достаточным).
Не-топорно требует цепочечного деления или base32/base64/etc. — облом такое кодить без нужды
Здравствуйте, TailWind, Вы писали:
TW>Закодировать проблем нет. Нужна концепция
Тогда концепция сводится к очень простой фразе: надо применить тот генератор случайных чисел, который предназначен для криптографии, а не тот, что для математических экспериментов типа метода Монте-Карло, когда важна воспроизводимость последовательности.
Потому что rand(), random(), lrand48(), Xorshift, вихрь Мерсенна и прочие из подобной группы они все именно для математических экспериментов. И они, соответственно, не годятся.
(Недавно в FB Шон Таунсенд пробегался по этому и по любителям применять дефолтные генераторы для нужд криптографии. Говорит, что вообще сейчас все стандартные библиотеки надо переделывать на непресказуемо случайные генераторы с криптографической надёжностью, чтобы, наоборот, предсказуемость была только следствием явного решения, а не наоборот. Мысль не нова, но столь чётко оформленной я её раньше не видел.)
Здравствуйте, netch80, Вы писали:
N>Можно, но если, например, 36 символов возможно в пароле (26 английских букв и 10 цифр), а мы берём по 1 байту входа на символ выхода... 256 делим на 36, в остатке 4 — это значит, что первые 4 в наборе будут генерироваться чаще, чем остальные (на 1/7 чаще). N>Эффект не сильно большой, но для серьёзной секьюрити может влиять. N>Если больше набор (до 70 символов можно позволить), эффект ещё сильнее, типа 1/3 разницы. N>А если делить на входе числа от 0 до 2**64-1, эффект становится неизмеримо малым. N>Это то, почему std::hash()() должен выдавать size_t (я удивлён, что не uintmax_t, но, видимо, сочли достаточным). N>Не-топорно требует цепочечного деления или base32/base64/etc. — облом такое кодить без нужды
Берёшь остаток от деления на 64. Если результат меньше 36, возвращаешь его. Иначе генерируешь новое число. Способ простой и даёт равномерное распределение.
Хотя для пароля проще взять 32 или 64 разных символа. Тогда заморачиваться не надо.
Здравствуйте, mike_rs, Вы писали:
_>без знания времени генерации восстановить не получится
Перебрать возможные значения time() может быть куда быстрей, чем перебрать пароли. time() возвращает время в секундах. Это всего лишь 31.5 млн вариантов, если известен хотя бы год. А уж если можно вывести точное время, к примеру по времени модификации какого-то файла, то там уже безопасность можно считать нулевая.
В общем я бы сказал, что это ОЧЕНЬ плохой вариант, сорри.
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
...
Может воспользоваться функциями для генерации псевдослучайных значений из <random>.
Например Равномерное распределение
Здравствуйте, TailWind, Вы писали:
TW>Это всё равно основано на rand() TW>Значит любой человек, используя disassembler сможет восстановить этот алгоритм и предсказывать ваши пароли
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
TW>Нужно чтобы между символами и паролями не было математической зависимости
#include <iostream>
#include <random>
int main()
{
std::random_device rd; // a seed source for the random number engine
std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<char> distrib('0', 'z');
// Use distrib to transform the random int
// generated by gen into an char in ['0' ... 'z']for (int n = 0; n != 24; ++n)
std::cout << distrib(gen);
std::cout << '\n';
}
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
TW>Нужно чтобы между символами и паролями не было математической зависимости
#include <iostream>
#include <random>
int main()
{
std::random_device rd; // a seed source for the random number engine
std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<char> distrib('0', 'z');
// Use distrib to transform the random int
// generated by gen into an char in ['0' ... 'z']for (int n = 0; n != 24; ++n)
std::cout << distrib(gen);
std::cout << '\n';
}