Безопасное удаление файла в C#.NET

В проекте, который я делаю, я хочу предоставить пользователям возможность «безопасного» удаления файла — например, перезаписать его случайными битами или нулями. Есть ли простой способ сделать это в С#.NET? И насколько это было бы эффективно?


person Chris    schedule 10.11.2010    source источник
comment
возможный дубликат уничтожения файлов в .NET   -  person Darin Dimitrov    schedule 10.11.2010
comment
Вы полностью упустили смысл моего ответа, нет никакого способа гарантировать, что данные, которые вы пытаетесь записать в файл, действительно будут занимать то же место на диске, что и данные, которые они заменяют, поэтому вы не можете делать то, что вы спрашивать.   -  person mikerobi    schedule 10.11.2010
comment
Вы хотите безопасно удалить содержимое или хотите перезаписать его случайными битами? Они не одинаковы. Думаю, просто перезаписать файл не получится.   -  person Steve Townsend    schedule 10.11.2010
comment
@mikerobi - это чрезвычайно сложно (особенно из C #), но не невозможно.   -  person Steve Townsend    schedule 11.11.2010
comment
возможный дубликат [C# - окончательное удаление файла](stackoverflow .com/questions/3330427/)   -  person Ben Voigt    schedule 30.12.2010


Ответы (5)


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

Используя API дефрагментации, SDelete может точно определить, какие кластеры на диске заняты данными, принадлежащими сжатым, разреженным и зашифрованным файлам.

Если вы хотите переупаковать эту логику в более удобную форму, API описан здесь.

person Steve Townsend    schedule 10.11.2010

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

ИЗМЕНИТЬ

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

Кажется, Microsoft предоставляет инструмент безопасного удаления, но, похоже, его нельзя использовать в качестве замены.

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

person mikerobi    schedule 10.11.2010
comment
Спасибо за ответ, немного переформулировал вопрос. Неважно, стерт ли файл полностью, важно лишь то, что я использую методы, аналогичные стандартной программе стирания файлов. - person Chris; 10.11.2010
comment
@Андрей, я не понимаю, что ты имеешь в виду - person mikerobi; 10.11.2010
comment
если файл имеет размер, скажем, 100 МБ, совершенно нецелесообразно хранить все зашифрованные и исходные файлы в ОЗУ... - person DividedByZero; 26.08.2014

Это вообще небезопасно. Вместо этого вы можете рассмотреть альтернативные решения, такие как шифрование.

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

Вот более подробное объяснение того, почему "безопасная" перезапись файлов небезопасна:

Без инструмента низкого уровня (вне среды выполнения .net) у вас нет доступа к расположению на физическом диске. Возьмите файловый поток на NTFS, когда вы «открываете файл для записи», у вас нет гарантии, что «обновленная» копия (в данном случае случайная версия 101010) будет храниться в том же месте (таким образом перезаписывая исходный файл). На самом деле чаще всего происходит вот что:

1) Файл x.dat хранится, начиная с кластера 8493489 2) Вы открываете файл x.dat для записи. То, что возвращает вам ОС, — это просто указатель на файловый поток, абстрагированный не только ОС, но и базовой файловой системой и драйверами устройств (например, аппаратным RAID), а иногда и самим физическим диском (SSD). Вы обновляете содержимое файла случайными 1 и 0 и закрываете файловый поток.

3) ОС, вероятно, может (и, вероятно, будет) записать новый файл в другой кластер (скажем, кластер 4384939). Затем он просто обновит MFT, указав, что файл x теперь хранится по адресу 4384939.

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

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

person Gerald Davis    schedule 10.11.2010
comment
файл нельзя восстановить без ключа, так что он в основном потерян, верно? неправильный. ключ ТАКЖЕ можно восстановить так же, как и файл, если кто-то точно не знает, что он делает - person DividedByZero; 26.08.2014


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

person Vilx-    schedule 10.11.2010
comment
Он не будет работать ни с одной файловой системой журналирования, независимо от типа диска (см. мой ответ для объяснения). - person mikerobi; 10.11.2010
comment
@mikerobi - я знаю, но помимо этого - это следующая лучшая вещь. По крайней мере, типичные утилиты восстановления будут обмануты. - person Vilx-; 11.11.2010