Я вот проверил: 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, которым честность случайности.