Создание вектора инициализации

Моя программа подключается к серверу, открытый ключ сервера уже известен. Затем программа шифрует ключ AES вместе с вектором инициализации и отправляет его на сервер. Сервер расшифровывает сообщение, и с этого момента для шифрования разговора используется AES.

Мой вопрос о том, как создать IV. Если я пойду наивным путем и заполню псевдослучайный генератор текущим временем, злоумышленник, вероятно, сможет сделать несколько очень хороших предположений о IV, что, черт возьми, не то, что мне нужно.

Поскольку аппаратные генераторы случайных чисел не только медленные, но и не везде доступны, я хотел бы пойти на другой подход. При первом запуске клиентской программы я позволяю пользователю сделать несколько случайных движений мышью, как это делает TrueCrypt. Теперь я сохраняю эти «случайные биты», созданные движением мыши, и когда мне понадобится генератор, я буду использовать их в качестве семени. Конечно, случайные биты должны обновляться каждый раз, когда я использую их в качестве начальных значений. И это мой вопрос: я подумал о том, чтобы просто сохранить первые несколько случайных битов, сгенерированных как новые «случайные биты». (Поэтому они привыкли инициализировать механизм случайных чисел при следующем запуске программного обеспечения.) Теперь я не уверен, будет ли это достаточно случайным или генераторы псевдослучайных чисел будут показывать здесь угадываемые закономерности. (Я бы, вероятно, использовал std::mt19937 http://en.cppreference.com/w/cpp/numeric/random)

Редактировать: режим цепочки меняется, поэтому я хочу, чтобы он работал в режиме с «самыми высокими» требованиями. Который был бы CBC, если я правильно помню.

Обратите внимание: программное обеспечение, которое я пишу, является чисто экспериментальным.


person cooky451    schedule 23.11.2012    source источник
comment
Вероятно, лучше подходит для crypto.stackexchange.com?   -  person Duncan Jones    schedule 24.11.2012
comment
IV — это одноразовый номер, предназначенный для предотвращения того, чтобы шифрование одного и того же открытого текста с одним и тем же ключом всегда создавало один и тот же зашифрованный текст.   -  person Dan D.    schedule 24.11.2012
comment
@DuncanJones Может быть... наверное. ;)   -  person cooky451    schedule 24.11.2012


Ответы (3)


Используйте криптографический PRNG, как вы делаете это для ключа.

В Windows используйте CryptGenRandom/RtlGenRandom, а в Linux/Unix используйте /dev/urandom. Они загружаются операционной системой, поэтому вам не нужно об этом заботиться.

Если вы действительно хотите создать свой собственный PRNG, загляните в Fortuna. Не используйте твистер Мерсенна.

person CodesInChaos    schedule 24.11.2012
comment
Итак, если я использую свой метод перемещения мыши вместе с криптографически безопасным PRNG, таким как Fortuna, случайные числа, которые я получаю, достаточно случайны, чтобы использовать их в качестве начальных значений при следующем запуске программы? Есть ли какой-либо известный предел этому? Должен ли я обновлять случайность пользователем после того, как программа x перезапустит / сгенерирует семена? - person cooky451; 24.11.2012
comment
Основная проблема заключается в том, что вы не должны испускать никаких случайных чисел, пока не накопите достаточно начальной энтропии. И это трудно оценить. - person CodesInChaos; 24.11.2012
comment
Ну, я имею в виду, что начальная энтропия не должна быть проблемой, я думаю, что случайные движения мыши в течение 30 секунд являются неплохим источником энтропии. Вопрос в том, как долго я могу использовать сгенерированные затем случайные числа в качестве начального числа, прежде чем мне снова придется просить пользователя выполнить трюк с мышью. - person cooky451; 24.11.2012
comment
@cooky451 1) Используйте системные API. Они лучше, чем все, что вы можете приготовить. 2) В принципе сид хорош или почти неограниченное количество данных. 3) ваши практические проблемы будут заключаться в повторном использовании случайных данных после того, как ваше постоянное хранилище будет сброшено до более старого значения. Поэтому мне не нравятся постоянные магазины для этого. - person CodesInChaos; 24.11.2012
comment
1) Цель этого проекта - чему-то научиться, я не хочу использовать системные API. Я знаю, что это проще, но цель здесь не в том, чтобы что-то сделать. 3) Я не понимаю. Под постоянным хранилищем вы имеете в виду состояние PRNG? - person cooky451; 24.11.2012
comment
Сохранение состояния PRNG между запусками вашего приложения нетривиально. - person CodesInChaos; 24.11.2012
comment
Почему? Я должен предположить, что сам компьютер в любом случае защищен, поэтому я действительно не вижу никаких проблем с сохранением состояния генератора на жестком диске? - person cooky451; 24.11.2012
comment
ИМО, такое постоянное состояние — это несчастный случай, ожидающий своего часа. 1) Если вы используете SSD, это значение не может быть удалено надежным способом =› нет прямой секретности, атаки уборщика и т. д. 2) Возможно повторное использование состояния. Например, из-за сбоев, восстановления из резервной копии, клонирования ВМ, запуска приложения дважды одновременно,... - person CodesInChaos; 24.11.2012
comment
1) Это не в моих интересах, как я уже сказал, я предполагаю, что окружающая среда безопасна. 2) Хм. Это действительно может быть проблемой. Сбои -> Сохраняю использованный флаг. Дважды запустить приложение или скопировать его. (Он будет мобильным.) -> Арх. Я мог бы выполнить xor состояния с помощью хэша SHA2 системного времени. Любые идеи? - person cooky451; 24.11.2012
comment
1) То, что устройство защищено сейчас, не означает, что оно будет безопасным и в будущем. Его могут украсть... 2) вы должны добавить столько энтропии, сколько сможете найти при запуске. Включая идентификатор процесса и время. Но не делайте xor в состоянии, передайте все части хеш-функции. - person CodesInChaos; 24.11.2012
comment
1) Я предполагаю, что само устройство зашифровано, иначе я все равно не сохраню состояние. ;) 2) Я стараюсь, чтобы системно-зависимые части были низкими, поэтому идентификатор процесса - это не то, что я хотел бы использовать. Но ладно, думаю, я знаю, что делать. Спасибо. - person cooky451; 24.11.2012

Вы должны уточнить, какой режим цепочки вы планируете использовать. От этого сильно зависят требования безопасности к вектору инициализации.

Например, в режиме CBC IV должен быть непредсказуемым и уникальным. Для режима CTR он может быть только уникальным, не обязательно непредсказуемым.

person SquareRootOfTwentyThree    schedule 24.11.2012

Генераторы псевдослучайных чисел хороши для вещей, когда вы не хотите, чтобы пользователи могли предсказывать результат (например, броски костей в играх), но бесполезны для случаев, когда вы не хотите, чтобы компьютер мог это вычислить. Для криптографии вообще не используйте псевдослучайность.

Если вам нужна случайность, вам нужны фактические случайные данные. Пока вы пишете, движения мыши являются хорошим источником для этого. Учитывая, что вы не говорите о /dev/random, я полагаю, вы работаете в Windows, которая, к сожалению, не собирает случайные числа во время работы. Так что вам придется сделать это самостоятельно. В зависимости от варианта использования вы можете запускать демон случайности при запуске, который продолжает собирать случайные данные и позволяет вашей программе извлекать их, когда это необходимо, или вы можете попросить пользователя сделать несколько движений мышью при запуске вашей программы.

Или вы можете решить, что если Windows не хочет, чтобы у вас были реальные случайные данные, вы не хотите использовать Windows, но я полагаю, что это не вариант. ;-)

person Bas Wijnen    schedule 24.11.2012
comment
Примечание: большинство аппаратных модулей безопасности (HSM) должны использовать PRNG, чтобы соответствовать криптографическим стандартам, например. FIPS 140-2, хотя обычно они посеяны из источников чистой случайности. - person Duncan Jones; 24.11.2012
comment
Windows собирает случайные данные при работе. - person President James K. Polk; 24.11.2012
comment
@GregS: Это так? Почему тогда такие программы, как putty, просят вас двигать мышью? - person Bas Wijnen; 24.11.2012
comment
@Bas Wijnen Просто взгляните на реализацию std::random_device в Windows. - person cooky451; 24.11.2012
comment
@cooky451: согласно msdn: класс описывает источник случайных чисел, предпочтительно с недетерминированного внешнего устройства. В этой реализации значения, полученные по умолчанию, не являются недетерминированными. В другом источнике (cppreference.com) говорится, что std::random_device — это генератор случайных чисел с равномерным распределением целых чисел, который генерирует недетерминированные случайные числа, если для реализации доступен недетерминированный источник (например, аппаратное устройство). . Похоже, это работает, только если у вас установлено специальное устройство случайного выбора, и оно не использует движения мыши и т. д. - person Bas Wijnen; 24.11.2012
comment
@BasWijnen stackoverflow.com/questions /9549357/ - person cooky451; 24.11.2012
comment
@cooky451: Интересно. Должно быть, тогда они изменили это. Хорошо, что они сделали. :-) - person Bas Wijnen; 24.11.2012
comment
Windows CryptGenRandom существует с 1990-х годов. - person President James K. Polk; 25.11.2012