Здравствуйте, 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';
}
Я вот проверил: Ubuntu 20.04, системный GCC. [UPD: ошибся. Оно через RDRAND читает.
А перед ним переключатель, который в зависимости от поддержки процессора меняет ссылку на функцию.]
Оценить насколько это хорошо не могу
Я даже не понимаю что значат флаги у CryptAcquireContext
Описание у функции на msdn не раскрывает используемых алгоритмов
Здравствуйте, TailWind, Вы писали:
TW>Оценить насколько это хорошо не могу TW>Я даже не понимаю что значат флаги у CryptAcquireContext TW>Описание у функции на msdn не раскрывает используемых алгоритмов
[skipped] TW>Оценить насколько это хорошо не могу TW>Я даже не понимаю что значат флаги у CryptAcquireContext TW>Описание у функции на msdn не раскрывает используемых алгоритмов
TW>Но наверно лучше чем велосипедить с rand()
Уж поверьте, Windows Crypto API это точно уж не лучше.
Накушаетесь Вы по полной программе.
Обсобенности разных версий Windows. В такой версии есть алгоритмец, а вот в такой нету.... С учетом выходок мелкомягких с версиями винды: премиумы, профессоналы, хоумы, воркстейшены которые как начались в районе Висты, так их и несет по кочкам.
Это просто полный вперед.
Накушался я оного в нулевые по самые по-нибалуйся.
Еще вдобавок: обсобенности конфигурации вообще конкретной машины с конкретной виндой.
Еще вдобавок: обсобенности настроек всякой разной секурной конфигурации.
Еще вдобавок: обсобенности всяких санкций! "А не будут брать, отключим газ ВинкриптоAPI"
Я тогда лет через три дерганий и бесконечных спотыканий у конкретных пользователей на конкретных машинах забил с прибором на эти Windows Crypto API. И просто сделал\адаптировал собственную реализацию.
Тем более, что это всего лишь генерация криптостойкого случайного числа. Охота Вам зависеть от всего вышеперечисленного? Оно Вам надо?
PS: и напоследок...
Все эти «обсобенности», они не складываются. Они умножаются друг на друга.
В результате на выходе получаем такое не слабое множество проблем!
Комбинаторика она сцуко штука такая.
В результате получаем картинку маслом: "Неважно насколько красив ваш код, если он не работает!" ((C) не помню кто)
Здравствуйте, TailWind, Вы писали:
TW>Что значат флаги PROV_RSA_FULL, CRYPT_VERIFYCONTEXT?
Мне стало интересно и я загуглил — мне хватило 5 минут, чтобы разобраться. Советую сделать то же самое, или спросить на SO — там любят давать обстоятельные ответы на простые вопросы.
Здравствуйте, Carc, Вы писали:
C>Я тогда лет через три дерганий и бесконечных спотыканий у конкретных пользователей на конкретных машинах забил с прибором на эти Windows Crypto API. И просто сделал\адаптировал собственную реализацию.
А случайные данные где берете? Вроде как нет разумной альтернативы системному источнику случайных данных.
Здравствуйте, vsb, Вы писали:
vsb>Берёшь остаток от деления на 64. Если результат меньше 36, возвращаешь его. Иначе генерируешь новое число. Способ простой и даёт равномерное распределение.
Только вот никто не гарантирует, что тебе на входе не поступят 100500 (или хотя бы 100) значений все которые дадут остаток 36 или больше. В результате алгоритм формально несходящийся, а на практике с неровными таймингами, через которые можно тоже что-то вычислить.
vsb>Хотя для пароля проще взять 32 или 64 разных символа. Тогда заморачиваться не надо.
Ну да, base32/base64 в этом смысле проще — если есть библиотека.
Здравствуйте, scf, Вы писали:
scf>Здравствуйте, TailWind, Вы писали:
TW>>Что значат флаги PROV_RSA_FULL, CRYPT_VERIFYCONTEXT?
scf>Мне стало интересно и я загуглил — мне хватило 5 минут, чтобы разобраться. Советую сделать то же самое, или спросить на SO — там любят давать обстоятельные ответы на простые вопросы.
Уважаемый, scf. Наши сотрудники работают над вашей проблемой. Скоро с Вами свяжутся наши сотрудники. Всегда Ваш роботЪ Сбера...
Тьфу, извините коллега. Навеяло.
Должно быть так
"Уважаемый, scf. На SO нужно песатьЪ на недружественным языке. На это мы пойтитЪ не могём".
Мне тоже как-то непонятно: простые вещи вроде что значит флаг, или что банальный rand не столь уж rand, топик-стартер готов обсасывать. Хотя зачем, если нагуглить\намсднить\нахабрить можно за минуту.
А вот суть обсуждать не стремится: именно зачем, для чего нужен такой-то или такой-то флаг, или почему так делать стоит или не стоит. и.т.д.
Не понимаю
Здравствуйте, scf, Вы писали:
scf>Здравствуйте, Carc, Вы писали:
C>>Я тогда лет через три дерганий и бесконечных спотыканий у конкретных пользователей на конкретных машинах забил с прибором на эти Windows Crypto API. И просто сделал\адаптировал собственную реализацию.
scf>А случайные данные где берете? Вроде как нет разумной альтернативы системному источнику случайных данных.
А мне тогда в 00-вые в самой задаче оказалось и не так уж нужно.
Ну, а где брать случайные данные вариантов тьма: HardwareID, SoftwareID, WindowsSessionID + "соль", а потом уж всё это хорошенько от`rand`ить...
Вообще говоря, ведь очевидно же от задачи придется плясать. Где нужно прям вот сильно случайное число, а где и просто rand`а достаточно...
scf>Мне стало интересно и я загуглил — мне хватило 5 минут
Мне не хватило
RSA — это метод шифрования. Каким боком тут случайные числа?
CRYPT_VERIFYCONTEXT — там про какие-то пары, ключи. То есть вообще не понятно каким боком к нашей теме
Здравствуйте, Carc, Вы писали:
TW>>Но наверно лучше чем велосипедить с rand() C>Уж поверьте, Windows Crypto API это точно уж не лучше. C>Накушаетесь Вы по полной программе.
У вас есть конструктивные предложения для Windows вместо CryptGenRandom()?
rand() и аналоги не предлагать, естественно.
Я подозреваю, что какой провайдер вызван у виндового крипто — будет для данного случая абсолютно пофиг, это мост-болванка, функциональность которой не интересует, и достаточно, чтобы его создание прошло успешно.
Здравствуйте, netch80, Вы писали:
vsb>>Берёшь остаток от деления на 64. Если результат меньше 36, возвращаешь его. Иначе генерируешь новое число. Способ простой и даёт равномерное распределение.
N>Только вот никто не гарантирует, что тебе на входе не поступят 100500 (или хотя бы 100) значений все которые дадут остаток 36 или больше. В результате алгоритм формально несходящийся, а на практике с неровными таймингами, через которые можно тоже что-то вычислить.
Если входной случайный генератор работает адекватно, то вероятность даже 10 итераций это < 1/2^10. Даже 20 это уже почти невероятно.
Если хочется убрать неровные тайминги, я бы предложил взять, к примеру, 6 * 64 битов, и в них найти первые 6 битов, которые меньше 33. И их выдать. А если таковых не нашлось, я бы вообще советовал сделать abort(), вероятность того, что исходный ГСЧ шпарит 0xff из-за бага, я бы оценил куда выше, чем вероятность того, что у нас произошло событие с вероятностью < 1/2^64. Тут я примерно так и сделал (:
Про тайминги не понял, что через них можно вычислить. Вроде ничего нельзя. Ну да, ты понимаешь, что исходный случайный генератор выдал несколько чисел, у которых нижние биты слишком большие. Если это нормальный криптографический генератор, по идее из этого ты никаких выводов сделать не можешь.
"allowed but not required to be non-deterministic or cryptographically secure"
Как-то это не слишком надёжно звучит. Ну если знать, что в конкретной реализации он безопасен, то без проблем.
К примеру в Java есть класс Random, а есть класс SecureRandom. Про второй разработчики JDK обещают, что он криптографически безопасен. И в реализации он и вправду читает из /dev/random для инициализации seed-а. Тут велосипед изобретать не нужно.
Здравствуйте, netch80, Вы писали:
N>У вас есть конструктивные предложения для Windows вместо CryptGenRandom()? N>rand() и аналоги не предлагать, естественно.
Альтернативу предложить можно. Все эти случайные генераторы всё равно не из астрала берут данные. Просто надёргать разных источников побольше и правильно скомбинировать. В линуксе есть rngd, можно его исходники почитать для вдохновения. Но, конечно, это задача другого уровня сложности, чем просто дёрнуть API, которое писали умные люди, читая умные диссертации.
Здравствуйте, vsb, Вы писали: vsb> ·>Вроде же уже есть в стандарте. Чем не подходит? vsb> ·>https://learn.microsoft.com/en-us/cpp/standard-library/random-device-class vsb> "allowed but not required to be non-deterministic or cryptographically secure" vsb> Как-то это не слишком надёжно звучит. Ну если знать, что в конкретной реализации он безопасен, то без проблем.
Ну так вроде обещают же: "In the Visual Studio implementation the values produced are non-deterministic and cryptographically secure".
Раз уж тут рекомендуют привязываться к страшному запутанному WinAPI, уж лучше стандартный класс с известной реализацией.
vsb> К примеру в Java есть класс Random, а есть класс SecureRandom. Про второй разработчики JDK обещают, что он криптографически безопасен. И в реализации он и вправду читает из /dev/random для инициализации seed-а. Тут велосипед изобретать не нужно.
Ага, и тут небольшая грабля есть, т.к. /dev/random очень медленный.
Здравствуйте, ·, Вы писали:
vsb>> К примеру в Java есть класс Random, а есть класс SecureRandom. Про второй разработчики JDK обещают, что он криптографически безопасен. И в реализации он и вправду читает из /dev/random для инициализации seed-а. Тут велосипед изобретать не нужно. ·>Ага, и тут небольшая грабля есть, т.к. /dev/random очень медленный.
Там грабля не совсем в этом была, грабля была в том, что /dev/random раньше мог блокироваться, если его кто-то активно вычитывал, а источники энтропии закончились. /dev/random читается именно на старте программы и это могло этот старт заморозить на неопределённое время.
Но в современном линуксе это исправили и там /dev/random и /dev/urandom по сути одинаковые. Поэтому про эту проблему, к счастью, можно забыть.
По поводу истинно случайного seed: если колхозить самому, то 2 хороших источника истинной случайности — это кадры с видеокамеры (объектив, закрытый "шторкой" — не помеха) и аудиоданные со звукового входа (хоть микрофонного, хоть линейного, отсутствие подключенного источника — не помеха), т.е. АЦП. Датчики температуры проца/материнки — тоже годятся. Любой АЦП шумит. Можно попытаться собрать только шум, используя N младших бит от каждого сабпикселя/сэмпла, но лучше тупо хешировать достаточный по размеру блок данных.
С доступом к этим устройствам, понятно, гемор, но, кажется, есть еще вариант: если в цикле замерять время исполнения одного маленького кусочка кода, то время будет каждый раз немножко разное, и немного истинной случайности в этом не может не быть (подразумевая, что речь идет о Windows/Linux, а не о микроконтроллерах и т.п.).
Замерять лучше функцией, использующей процессорную инструкцию rdtsc (надеюсь, есть в используемых стандартных библиотеках), как вариант — WinAPI-шной QueryPerformanceCounter.
Пример на коленке (100 голых вызовов этой самой rdtsc, результаты замеров в т.ч. побитно. Если что, сорри, я далек от С++):
#include <iostream>
#include <bitset>
#include <intrin.h> // есть не везде. на godbolt есть в MinGW (clang/gcc12). где-то - <x86intrin.h> (например, в ICC)#pragma intrinsic(__rdtsc)
int main() {
unsigned __int64 c = 0, c0;
int a[100];
for (int i = 0; i < 100; ++i) {
c0 = c; c = __rdtsc();
a[i] = c - c0;
}
for (int i = 0; i < 100; ++i) {
std::cout << a[i] << ' ' << std::bitset<8>(a[i]) << std::endl;
}
}
https://godbolt.org/z/3G4jd5eqc
Распределение сильно неравномерное, но закономерности явной нет. (На godbolt все чётные, на моём компе присутствует кратность трём...)
UPD: выкинул output из цикла замеров и попытку получить 1 "хороший" бит из нескольких.
Очевидно, лучше набрать побольше в байтах и захешировать всю последовательность.
Здравствуйте, netch80, Вы писали:
n> vsb>> Надо использовать /dev/random или аналог в винде. n> ·>Вроде же уже есть в стандарте. Чем не подходит? n> ·>https://learn.microsoft.com/en-us/cpp/standard-library/random-device-class n> Никто не гарантирует использование реального /dev/{random,urandom} в этом случае.
У него же "в винде", а там обещают.
n> Я вот проверил: Ubuntu 20.04, системный GCC. И что вы таки себе думаете — он включает встроенный в этот самый random_device... ещё один Mersenne Twister! И никакого /dev/random не читает. Картина Пикассо.
Странно. По крайней мере, вроде может. В исходниках он пытается что-то подоборать https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/src/c++11/random.cc#L330
Может он напрямую из CPU берёт?
И, вроде, у него есть метод entropy, которым честность случайности.
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
Набрать энтропии откуда-то, получить криптографический хэш какой-нибудь
или даже лучше HMAC (что-то типа KDF_GOSTR3411_2012_256).
Потом кодировать в base64 и отрезать 24 байта.
Откуда набрать качественной энтропии — вопрос...
Так-то желательно иметь нормальный CSP.
В линухе можно, как уже написали, читать /dev/urandom.
Насчет биологического датчика энтропии для гпсч (типа клавиатуру нажимать, мышью двигать)...
Там чтобы нормально энтропию набрать, специальные алгоритмы применяются.
У нас они проверены и сертифицированы фсб.
Но если что-то из интернетов навскидку... можно скачать сорцы TrueCrypt там вроде была рулетка.
З.Ы. не знаю насколько это может быть корректно.
Можно попробовать набрать плохой энтропии.
Попросить пользователя ввести несколько символов, добавить данные rdtsc, времени.
Потом из этого выработать ключ по PBKDF2, ключ кодировать в base64 и откусить нужный кусок.
Если юзать отечественную криптографию то там PRF будет — все тот же HMAC на гостовском хэше.
Здравствуйте, ·, Вы писали:
n>> Я вот проверил: Ubuntu 20.04, системный GCC. И что вы таки себе думаете — он включает встроенный в этот самый random_device... ещё один Mersenne Twister! И никакого /dev/random не читает. Картина Пикассо. ·>Странно. По крайней мере, вроде может. В исходниках он пытается что-то подоборать ·>https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/src/c++11/random.cc#L330 ·>Может он напрямую из CPU берёт?
Ты прав, а я запутался в отладчике. Он, оказалось, через RDRAND берёт данные.
·>И, вроде, у него есть метод entropy, которым честность случайности.
Здравствуйте, vsb, Вы писали:
vsb>Там грабля не совсем в этом была, грабля была в том, что /dev/random раньше мог блокироваться, если его кто-то активно вычитывал, а источники энтропии закончились. /dev/random читается именно на старте программы и это могло этот старт заморозить на неопределённое время.
vsb>Но в современном линуксе это исправили и там /dev/random и /dev/urandom по сути одинаковые.
Угу, в ванильке где-то с 5.12.
vsb>Про другие *nix не знаю.
FreeBSD так работала примерно с 2001-го. MacOS повторила её подход. Чем в Linux думали — не знаю, там в условном core team пачка настолько упрямых ослов была, что цензурных слов не было.
Здравствуйте, netch80, Вы писали:
n> Ты прав, а я запутался в отладчике. Он, оказалось, через RDRAND берёт данные.
n> ·>И, вроде, у него есть метод entropy, которым честность случайности. n> Так оно бы не помогло.
В смысле? Прога может проверять энтропию, и если 0 (что выдаётся в случае плохого prng источника), то сказать пользователю "извините, не шмогла" или подобное.
Трахаться с полу-стандартным winapi, подстраиваться под разные версии винды... как-то бессмысленно, когда это давно решили разработчики stdlib.
Здравствуйте, ·, Вы писали:
n>> ·>И, вроде, у него есть метод entropy, которым честность случайности. n>> Так оно бы не помогло. ·>В смысле? Прога может проверять энтропию, и если 0 (что выдаётся в случае плохого prng источника), то сказать пользователю "извините, не шмогла" или подобное.
Если бы оно само генерировало каким-то псевдоГСЧ, то с энтропией было бы всё в порядке, о чём бы оно честно и сказало.
·>Трахаться с полу-стандартным winapi, подстраиваться под разные версии винды... как-то бессмысленно, когда это давно решили разработчики stdlib.
Здравствуйте, netch80, Вы писали:
n> ·>В смысле? Прога может проверять энтропию, и если 0 (что выдаётся в случае плохого prng источника), то сказать пользователю "извините, не шмогла" или подобное. n> Если бы оно само генерировало каким-то псевдоГСЧ, то с энтропией было бы всё в порядке, о чём бы оно честно и сказало.
Опять же отправлю к тому же исходнику: case prng: return 0.0;.
n> ·>Трахаться с полу-стандартным winapi, подстраиваться под разные версии винды... как-то бессмысленно, когда это давно решили разработчики stdlib. n> В какой из полдесятка сборок?
Я не говорю, что это суперуниверсальное всемогучее решение всех проблем. Но это решение лучше по многим параметрам, чем предложенные тут альтернативы в виде cryptoapi и доморощенные алгоритмы.
Здравствуйте, TailWind, Вы писали:
TW>Не очень понятно как из этого сделать равномерное распределение TW>Проблема с rand() в том, что она повторяется каждые 3fff байт
так у вас от пользователя куча рандомных данных. Можно перед каждым вызовом rand задавать затравку. Да и в таком подходе rand не особо то и нужен. Фактически берёте от пользователя случайную последовательность, смешиваете с временной меткой и хешируете в своё удовольствие. Каждый следующий символ практически случаен.
SP>так у вас от пользователя куча рандомных данных
Мышка и клавиатура не рандомные
С большой вероятностью вы будите тыкать в клавиатуру по очереди правой и левой рукой
Правая рука будет тыкать чаще справа, левая слева
Наберите статистику на 100000 таких вводов и получите распределение наиболее вероятных комбинаций
Здравствуйте, TailWind, Вы писали:
SP>>так у вас от пользователя куча рандомных данных
TW>Мышка и клавиатура не рандомные TW>С большой вероятностью вы будите тыкать в клавиатуру по очереди правой и левой рукой TW>Правая рука будет тыкать чаще справа, левая слева
Когда говорится о таких данных, имеется в виду что-то вроде дробной части миллисекунды момента получения прерывания от клавиатуры/мыши с точностью до, например, 10 нс. А не какая клавиша и какой рукой нажата.
Но этой энтропии таки недостаточно, иначе бы всякие RDRAND не изобретали бы.
Здравствуйте, TailWind, Вы писали:
TW>Чем их измерять то, эти 10 нс?
RDTSC, RDTSCP считают до такта процессора, а это с частотой >=1GHz менее наносекунды.
HPET или APIC timer позволяют до 40-90 нс, это тоже неплохо (но к ним так просто не подобраться, если ОС не замапила их всем на чтение).
Здравствуйте, TailWind, Вы писали:
TW>Как сделать случайный пароль на 24 символа? TW>И потом ещё один такой же
TW>Нужно чтобы между символами и паролями не было математической зависимости
TW>То есть rand(), rand(), rand(), rand() не подходит
TW>Единственное, что мне пришло в голову rand(GetTickCount()) TW>Но этого мало. А дальше то как?
вся или почти вся(если строго) криптография основана на том, что злоумышленник знает все алгоритмы
так что исходить нужно из этого