Как очистить файлы, которые дешифруются во время выполнения, очищаются?

С помощью C или C ++ после дешифрования файла на диск – как я могу гарантировать, что он будет удален, если приложение выйдет из строя или система отключится и не сможет его правильно очистить? Использование C или C ++ в Windows и Linux?

Не записывайте файл, дешифрованный на диск.

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

Исключение – использование зашифрованной файловой системы, но это не контролирует вашу программу.

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

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

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

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

Я не знаю, работает ли это в Windows, но в Linux, предполагая, что вам нужен только один процесс для доступа к расшифрованному файлу, вы можете открыть файл, а затем вызвать unlink (), чтобы удалить файл. Файл будет продолжать существовать до тех пор, пока процесс не откроет его, но когда он будет закрыт или процесс исчезнет, ​​файл больше не будет доступен.

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

Попытайтесь избежать этого полностью:

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

Защита от сбоев: Управление структурированными исключениями:

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

__try и __except

Что делать, если они вытаскивают пробку ?:

Существует способ защиты от этого …

Если вы находитесь в windowsх, вы можете использовать MoveFileEx и параметр MOVEFILE_DELAY_UNTIL_REBOOT с пунктом назначения NULL для удаления файла при следующем запуске. Это защитит от случайного выключения компьютера с восстановленным файлом. Вы также можете убедиться, что у вас есть исключительно открытый дескриптор этого файла (не указывайте права доступа, такие как FILE_SHARE_READ, и используйте CreateFile, чтобы открыть его). Таким образом, никто не сможет прочитать это.

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

  • Вы также можете рассмотреть запись в файл, который больше MAX_PATH с помощью синтаксиса файла \\? \. Это гарантирует, что файл не будет доступен для просмотра в проводнике Windows.

  • Вы должны установить для файла временный атрибут

  • Вы должны установить для файла скрытый атрибут

В C (и так, я полагаю, в C ++ тоже), если ваша программа не сбой, вы можете зарегистрировать обработчик atexit() для очистки. Просто избегайте использования _exit() или _Exit() поскольку они обходят обработчики atexit() .

Однако, как отмечали другие, лучше избегать дешифровки данных, записанных на диск. И просто использовать unlink() (или эквивалент) недостаточно; вам нужно переписать некоторые другие данные по исходным данным. И журналированные файловые системы делают это очень сложным.

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

Вы можете сделать это с использованием hearth-beats (регулярный опрос другого процесса, чтобы узнать, жив ли он), или с помощью прерываний, отправленных из самого другого процесса, который вызовет таймаут, если он потерпел крах.

Например, вы можете использовать сокеты, чтобы соединение между сторожевым псом и вашим приложением работало, например.

Становится ясно, что вам нужен механизм блокировки, чтобы предотвратить обмен файлами подкачки / swap-раздела. В Posix Systems это может быть выполнено m(un)lock* family of functions .

Проблема с удалением файла. Это еще не все. Когда вы удаляете файлы с жесткого диска (не считая корзины), файл на самом деле не пропадает. Удаляется только указатель на файл.

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

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

Удачи.

Проверьте tmpfile ().

Он является частью BSD UNIX, не уверен, является ли он стандартным.
Но он создает временный файл и автоматически отключает его, чтобы он был удален при закрытии.

Запись в файловую систему (даже временно) небезопасна.
Сделайте это, только если вам действительно нужно.

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

В C ++ вы должны использовать тактику RAII :

 class Clean_Up_File { std::string filename_; public Clean_Up_File(std::string filename) { ... } //open/create file public ~Clean_Up_File() { ... } //delete file } int main() { Clean_Up_File file_will_be_deleted_on_program_exit("my_file.txt"); } 

RAII помогает автоматизировать большую очистку. Вы просто создаете объект в стеке и убираете этот объект в конце своего жизненного цикла (в деструкторе, который будет вызываться, когда объект выпадает из области видимости). ScopeGuard даже делает его немного легче.

Но, как говорили другие, это работает только в «нормальных» условиях. Если пользователь отключает компьютер, вы не можете гарантировать, что файл будет удален. Возможно, удастся восстановить файл (даже в UNIX можно « grep harddrive »).


Кроме того, как отмечалось в комментариях, есть некоторые случаи, когда объекты не выходят за frameworks (например, функция std::exit(int) выходит из программы, не выходя из текущей области), поэтому RAII не работа в этих случаях. Лично я никогда не вызываю std::exit(int) , и вместо этого я либо бросаю исключения (которые разматывают стек и вызывают деструкторы, что я считаю «аномальным выходом»), либо возвращают код ошибки из main() (который будет вызывают деструкторы, и я также рассматриваю «аномальный выход»). IIRC, отправка SIGKILL также не вызывает деструкторов, и SIGKILL нельзя поймать, так что вам тоже не повезло.

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

Я давно читал статьи об этом, и я помню, что между Windows и Linux существует некоторая разница в том, что можно было бы гарантировать, что страница памяти не будет записана на диск, и никто не сможет; но я не помню ясно.

Если вы хотите проявить должную осмотрительность, вы можете посмотреть эту тему и прочитать об этом. Все зависит от вашей модели угрозы и от того, что вы готовы защищать. В конце концов, вы можете использовать сжатый air для охлаждения ОЗУ и вытаскивать из него ключ шифрования (который был на самом деле на новом шпионском шоу Christian Slater, My Own Worst Enemy), который, как я думал, был лучшим использованием ультрасовременного, точного, компьютерного техники безопасности в средствах массовой информации)

на Linux / Unix, используйте unlink, как только вы создали файл. Файл будет удален, как только вы закроете файловый дескриптор или завершите работу.

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

Разумеется, данные не будут физически удалены с диска, поэтому они могут быть доступны для взлома.

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

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

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

Затем ваша система должна быть защищена от атак, за которыми не срабатывают враги, прерывая вас и замораживая ваши чипы RAM перед отключением, поэтому они не теряют свое содержимое перед передачей на экспертизу. Или власти, требующие вашего ключа, юридически (проверьте ваши местные законы здесь) или незаконно.

Мораль истории: реальная безопасность сложна.

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

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

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

Эта реализация не требует от меня расшифровки файла или памяти и совместима с другими пользователями и поставщиками streamов (fstream).

Это мой «план». Я раньше не делал такого рода работы с fstream, и я, скорее всего, отправлю вопрос, как только я готов работать над этим.

Спасибо за все остальные ответы – это было очень информативно.