2013-05-11 7 views
13

Я работаю над приложением C++, которое хранит некоторые секретные ключи пользователя в ОЗУ. Эти секретные ключи очень чувствительны. & Я должен минимизировать риск любого нападения на них.
Я использую массив символов для хранения этих ключей, я прочитал некоторое содержание о хранении переменных в регистры процессора или даже кэша ЦП (т. Е. Используя ключевое слово C++ register), но, похоже, нет гарантированного способа заставить приложение хранить некоторые из его переменных вне RAM (я имею в виду в регистры процессора или кеш).
Может ли кто-нибудь предложить хороший способ сделать это или предложить любое другое решение для безопасного хранения этих ключей в ОЗУ (я ищу независимое от ОС решение)?как сохранить переменные C++ в оперативной памяти?

+2

Вы задаете правильный вопрос? Мне кажется, что если вы беспокоитесь о том, что ключи были украдены из энергозависимой памяти, ваши усилия будут лучше потрачены на обеспечение физического расположения оборудования. –

+0

Если я беспокоюсь о физическом местоположении, это связано с тем, что я знаю, что гораздо легче стереть конфиденциальные данные из ОЗУ (т. Е. Использовать холодную загрузку), но на самом деле место хранения не является основной проблемой, если я могу гарантировать безопасность данных в ОЗУ, тогда я буду удовлетворять! –

+0

Будет ли защищен физический доступ к ОЗУ в вашем приложении? Если не защита программного обеспечения не поможет, некоторые SDRAM сохраняют информацию в течение минуты после выключения даже при комнатной температуре. –

ответ

18

Ваши намерения могут быть благородными, но они также ошибочны. Короткий ответ заключается в том, что нет никакой возможности сделать то, что вы хотите, в системе общего назначения (т. Е. Товарных процессорах/материнской плате и O/S общего назначения). Даже если бы вы могли каким-то образом заставить вещи хранить только на процессоре, это все равно не помогло бы. Это будет всего лишь небольшая неприятность.

В более общем плане, для защиты памяти существуют специальные решения O/S, указывающие, что память блоков не должна быть записана в файл подкачки, такой как функция VirtualLock в Windows. Это стоит использовать, если вы выполняете криптографию и сохраняете конфиденциальные данные в этой памяти.

Последнее: я хочу отметить, что меня беспокоит то, что у вас есть фундаментальное непонимание ключевого слова register и его последствий для безопасности; помните, что это намек, и это не будет - действительно, не может - заставлять что-либо фактически хранить в регистре или в другом месте.

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

+4

Я бы сказал, что он атакует систему легче, если они находятся в регистре. Если вы знаете, где находятся данные, это половина битвы. Единственное преимущество ОЗУ над ЦП состоит в том, что есть много всего для поиска (но опять же, если вы знаете, где это, тогда его не сложно извлечь (с помощью правильных инструментов). –

+0

@LokiAstari Я полностью согласен - как Я сказал, что ОП ошибочен. –

+7

ОП не ищет гарантий безопасности, только минимизация. Вы слишком суровы, особенно если говорить, что он не квалифицирован. Мы все здесь, чтобы учиться. –

5

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

Вы можете создать некоторые функции, такие как «выделить безопасную память» (что по умолчанию звонки malloc) и «свободной защищенной памяти» (что по умолчанию вызовы memset и затем free), а затем использовать их. Возможно, вам придется делать другие вещи (например, блокировать память, чтобы ваши ключи не сворачивались на свопе) на платформах, где нужны другие вещи.

+0

& что вы предлагаете, если я ограничусь архитектурой ОС Windows и Intel x86? –

+1

Дополнительный материал относится к каждой платформе. Windows имеет 'VirtualLock', некоторые UNIX имеют' mlock'. –

1

Если ваша платформа поддерживает POSIX, вы должны использовать mlock, чтобы предотвратить пересылку данных в область подкачки. Если вы пишете код для Windows, вместо этого вы можете использовать VirtualLock.

Имейте в виду, что нет абсолютного способа защиты конфиденциальных данных от утечки, если вам требуется, чтобы данные были в незашифрованном виде в любой момент времени в ОЗУ (мы говорим об простой ОЗУ здесь, ничего необычного, как TrustZone). Все, что вы можете сделать (и надеетесь), состоит в том, чтобы свести к минимуму время, в течение которого данные остаются незашифрованными, чтобы у противника было меньше времени, чтобы воздействовать на него.

0

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

Я когда-то видел некоторые платформы, имеющие дело с очень разумными данными, в которых были обнаружены датчики, когда кто-то физически обращался к машине, и которые активно удаляли данные, когда это было так.

Вы уже упоминали атаку на холодную войну, проблема в том, что доступ к данным в ОЗУ можно получить до нескольких минут после выключения общей памяти.

2

Помимо замечаний, приведенных выше, вы должны учитывать, что даже если вы хотите сохранить ключ в регистрах, вам будет необходимо учесть, что содержимое регистра, скорее всего, будет храниться в памяти при входе прерывания и/или когда другая задача запускается на машине. И, конечно, кто-то с физическим доступом к машине может запускать отладчик и проверять регистры. Отладчик может быть «в эмуляторе схемы», если ключ достаточно важен, чтобы кто-то потратил несколько тысяч долларов на такое устройство, что вовсе не означает программного обеспечения в целевой системе.

Другой вопрос, конечно, насколько это важно. Откуда берутся ключи? Кто-то печатает их? Если это не так, и они хранятся где-то в другом месте (в коде, на сервере и т. Д.), Они в какой-то момент будут храниться в памяти, даже если вам удастся сохранить их в памяти, когда вы действительно используете ключи. Если кто-то печатает их, не является ли угроза безопасности тем или иным способом, заставляет человека (ов) знать ключи, чтобы выявить ключи?

6

Вы не можете устранить риск, но можете его смягчить.

Создайте единую область статической памяти, которая будет единственным местом, где вы когда-либо храните ключи cleartext. И создайте единый буфер случайных данных, который вы будете использовать для любых ключей, которые не хранятся в этом статическом буфере.

Всякий раз, когда вы читаете ключ в память, из ключевого файла или что-то еще, вы читаете его непосредственно в этом статическом буфере, xor с вашими случайными данными и копируете его там, где вам это нужно, и сразу очищаете буфер нулями ,

Вы можете сравнить любые два ключа, просто сравнив их маскированные версии. Вы даже можете сравнить хэши скрытых ключей.

Если вам нужно работать с ключом открытого текста - например, для генерации хэша или проверки их ключей каким-то образом загружает скрытый ключ в xor'ed в этот один статический буфер, xor его обратно в cleartext и использовать его. Затем записывайте нули обратно в этот буфер.

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

Если кто-то попытался атаковать с холодным ботинком, потянув за вилку на аппаратное обеспечение и проверив чипы памяти, будет только один буфер, который может содержать ключ cleartext, а шансы - в этот конкретный момент времени coldboot attack буфер будет пустым.

При работе с ключом вы можете даже разоблачить только одно слово ключа за раз перед тем, как оно понадобится, чтобы проверить ключ таким образом, чтобы в этом буфере никогда не хранился полный ключ.

@update: Я просто хотел бы рассмотреть некоторые критические замечания в комментариях ниже:

Фраза «безопасность через неизвестность» обычно понимается неправильно. При формальном анализе алгоритмов безопасности «скрытность» или методов скрытия данных, которые не являются криптографически безопасными, не повышается формальная безопасность криптографического алгоритма. И это правда в этом случае. Учитывая, что ключи хранятся на компьютере пользователя и должны использоваться этой программой на этой машине, ничего не может сделать, чтобы криптографически защитить ключи на этом компьютере. Независимо от того, какой процесс вы используете, чтобы скрыть или заблокировать данные в какой-то момент, программа должна его использовать, и определенный хакер может поместить контрольные точки в код и посмотреть, когда программа использует данные. Но никакие предложения в этой теме не могут устранить этот риск.

Некоторые люди предположили, что OP найдет способ использования специального оборудования с заблокированными микросхемами памяти или некоторым способом блокировки чипа операционной системы. Это криптографически не более безопасно. В конечном счете, если у вас есть физический доступ к машине, достаточно известный хакер может использовать логический анализатор на шине памяти и восстанавливать любые данные. Кроме того, ОП заявила, что целевые системы не имеют такого специализированного оборудования.

Но это не означает, что вы не можете сделать что-то, что можно сделать для снижения риска. Возьмите простейший из ключей доступа - пароль. Если у вас есть физический доступ к машине, вы можете поместить в регистратор ключей или получить дампы памяти запущенных программ и т. Д. Так что формально пароль не более безопасен, чем если бы он был написан в виде открытого текста на клейкой ноте, приклеенной к клавиатуре. Тем не менее, все знают, что держать пароль на липкой ноте - плохая идея, и это плохая практика для программ, позволяющих отсылать пароли пользователю в виде открытого текста. Потому что, конечно, практически говоря, это резко снижает планку для атакующего. Однако формальная заметка с паролем не менее безопасна.

Предлагаемое мной предложение имеет реальные преимущества в области безопасности. Ни одна из деталей не имеет значения, кроме маскировки ключей «xor» ключей безопасности. И есть способы сделать этот процесс немного лучше. Xor'ing клавиши ограничивают количество мест, которые программист должен учитывать как векторы атак. Как только ключи являются xord, у вас могут быть разные ключи по всей вашей программе, вы можете их скопировать, записать в файл, отправить их по сети и т. Д. Ни одна из этих вещей не поставит под угрозу вашу программу, если злоумышленник не имеет буфера xor. Итак, есть ОДИНОЧНЫЙ БУФЕР, о котором вам нужно беспокоиться. Затем вы можете расслабиться вокруг каждого буфера в системе. (и вы можете mlock или VirtualLock, чтобы один буфер)

После того, как вы очистили этот буфер xor, вы постоянно и надежно устраняете любую возможность того, что злоумышленник может восстановить любые ключи из дампа памяти вашей программы. Вы ограничиваете свою экспозицию как по количеству мест, так и по времени, когда ключи могут быть восстановлены. И вы создаете систему, которая позволяет вам легко работать с ключами, не беспокоясь при каждой операции над объектом, содержащей ключи о возможных простых способах восстановления ключей.

Таким образом, вы можете представить себе, например, систему, в которой ключи пересчитывают буфер xor, и когда все ключи больше не нужны, вы нулевое и удаляете буфер xor, и все ключи становятся недействительными и недоступными без необходимости отслеживать их и беспокоиться о том, что страница памяти была заменена и все еще содержит ключи открытого текста.

Вам также не нужно буквально хранить буфер случайных данных. Например, вы можете использовать криптографически безопасный генератор случайных чисел и использовать одно случайное семя для генерации буфера xor по мере необходимости. Единственный способ, которым злоумышленник может восстановить ключи, - это доступ к отдельному семенному генератору.

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

+3

Отличный ответ. лучший из них - +1, потому что я могу только его перенести. –

+1

@Freedom_Ben Этот ответ ошибочен (например, этот буфер можно было поместить в ОЗУ), и я не уверен что он действительно достигает, если что-то.На самом деле, зная, что конкретный виртуальный адрес всегда будет тем, который хранит конфиденциальные данные в какой-то момент времени, позволяет * EASIER * монтировать атаку: установить аппаратные точки останова, которые запускаются при изменении этого виртуального адреса. Я скажу это еще раз и сделаю это очень просто: если у злоумышленника есть физический доступ к машине, это ** ИГРА НАЗАД **, и есть ** НИЧЕГО **, которое может сделать программное обеспечение для предотвращения этого, даже не XOR. –

+2

Это совершенно не имеет никакого смысла. Схема XOR является идиотской по ряду причин. Один из них заключается в том, что все злоумышленники должны найти место, где хранятся основные данные XOR, сделать XOR, и все. Другим является то, что он полностью уязвим для различных атак, таких как известный открытый текст. Вероятно, это не принесет никакого вреда, если никто не будет полагаться на него, а также другие разумные вещи, предлагаемые другими, но если кто-то ожидает, что это обеспечит некоторую степень безопасности и будет полагаться на него, произойдет очень плохое. –

2

Как говорили другие, нет надежного способа сделать это на компьютере общего назначения. Альтернативой является использование Hardware Security Module (HSM).

Они обеспечивают:

  • больше физической защиты для ключей, чем обычные ПК/сервера (защита от прямого доступа к памяти);
  • большая логическая защита, поскольку они не являются общим назначением - на компьютере не работает другое программное обеспечение, так что другие процессы/пользователи не имеют доступа к ОЗУ.

API-интерфейс HSM можно использовать для выполнения необходимых криптографических операций (при условии, что они являются стандартными), не выставляя незашифрованный ключ вне HSM.

+0

Я думал о включении ссылки на криптопроцессоры IBM в свой ответ, но был немного поспешным, когда я это написал. Спасибо за публикацию. –

0

Если ваш пользовательский режим приложения и память, которую вы пытаетесь защитить, из других процессов пользовательского режима попробуйте CryptProtectMemory api (не для постоянных данных).

Смежные вопросы