我想使用PHP删除文件。我使用了unlink()
函数,但我想知道unlink
的安全性。文件是否已从服务器中完全删除?我想确保无法恢复文件,并且文件已从服务器中完全删除。
答案 0 :(得分:50)
以二进制模式打开文件进行写入,在整个文件上写入1,关闭文件,然后取消链接。覆盖文件中的任何数据,使其无法恢复。
就我个人而言,我会说使用1而不是0,因为1是实际数据并且将始终写入,而0可能不会写,这取决于几个因素。
编辑:经过一番思考和阅读评论后,我会采用混合方法,具体取决于您希望文件“删除的方式”,如果您只是希望如此数据无法恢复,用1来快速覆盖整个文件长度,因为这很快,并且破坏了数据,这个问题是,它在磁盘上留下了一定长度的统一数据,它推断出文件USED在那里并给出远离文件长度,提供重要的法医信息。简单地写随机数据也不会避免这种情况,就好像这个文件周围的所有驱动扇区都不受影响一样,这也会留下一个取证痕迹。
分析取证删除,混淆和合理拒绝的最佳解决方案(再次,这是过度杀伤,但我为了添加它而添加它),用1的覆盖文件的整个长度然后,对于HALF文件的长度(以字节为单位),从随机起始点的随机长度大小的mt_rand
写入,留下许多不同长度的文件曾经在此区域中的印象,从而产生错误落后。 (再次,这是完全矫枉过正的,通常只有连环杀手和CIA才需要,但是为了这样做,我加入它。)
答案 1 :(得分:11)
重新编写代码示例,使用像PHP这样的语言对于这种类型的擦除是错误的,因为你在操作系统上的中继真的擦除了文件并且没有做一些切割器,比如最后一次擦除或只是取消链接,但是...
(未测试的)
$filename = "/usr/local/something.txt";
$size = filesize($filename);
$pat1 = chr(0);
$pat2 = chr(255);
$pat3 = chr(170);
$pat4 = chr(85);
$mask = str_repeat($pat1, $size);
file_put_contents($filename, $mask);
$mask = str_repeat($pat2, $size);
file_put_contents($filename, $mask);
$mask = str_repeat($pat3, $size);
file_put_contents($filename, $mask);
$mask = str_repeat($pat4, $size);
file_put_contents($filename, $mask);
答案 2 :(得分:4)
这可能无法回答如何完全删除“使用PHP”文件,但它回答了您的问题:“该文件是否已从服务器中完全删除?”
根据对offical PHP unlink() manual page的最高投票评论,取消链接功能不会真正删除该文件,它正在删除指向该文件内容的系统链接 !由于文件可以有多个文件名(!)[符号链接?],因此只有在取消链接所有文件名时才会删除该文件。因此,如果您的文件有2个名称,那么unlink()将不会真正删除该文件,除非您取消链接()两个文件名。亲爱的linux家伙,如有必要,请在这里纠正我。
这里有一篇优秀评论的完整引用:
删除了一个大文件但是没有增加可用空间或减少磁盘使用量?使用UNIX或其他POSIX OS? unlink()不是关于删除文件,而是关于删除文件名。该联机帮助页显示:
`unlink - delete a name and possibly the file it refers to''. Most of the time a file has just one name -- removing it will also remove (free, deallocate) the
body'文件(有一点需要注意,见下文)。这是一个简单的常见案例。 但是,文件在相同或不同的目录中具有多个名称(请参阅link()函数)是完全正确的。所有名称都将通过保持文件打开的进程引用文件正文并保持keep it alive', so to say. Only when all the names are removed, the body of file actually is freed. The caveat: A file's body may *also* be
保持活动状态(仍使用磁盘空间)。只要进程保持打开状态,主体就不会被释放(不会释放磁盘空间)。事实上,有一种奇特的方法可以恢复由错误删除的文件,但仍然由一个进程保持打开...
查看unlink()
的姐妹函数link()
here。
使用PHP(在linux中)真正删除文件的方法是使用exec()
函数,该函数执行真正的bash命令(使用linux bash做事情感觉正确顺便说一下)。在这种情况下,文件test.jpg
将通过执行以下操作删除:
exec("rm test.jpg);
有关如何正确使用rm
(删除)的详细信息,请参阅here。请注意:PHP需要有权删除该文件!
更新:不幸的是,linux rm
命令如果有两个名称/链接,也不会真正删除该文件。 Look here了解更多信息。
我将对此进行更深入的研究并提供反馈......
答案 3 :(得分:2)
由于磁盘上存在一些碎片,因此文件的某些部分可能会保留,即使文件被完全覆盖也是如此。
另一种方法是运行(通过shell_exec()
)外部程序,这是系统特定的。 Here is an example(对于Windows),但我还没有测试过它。
答案 4 :(得分:0)
以下是EFF建议永久删除文件http://ssd.eff.org/tech/deletion。
答案 5 :(得分:0)
你应该多次覆盖以消除痕迹。例如,使用美国国防部5220-22.M:“用一个字符覆盖所有可寻址的位置,它的补码,然后一个随机字符并验证”(来自killdisk网站)
答案 6 :(得分:0)
在我的嵌入式Ubuntu设备中,我使用:echo exec('rm /usr/share/subdirectory/subdirectory/filename');
这适用于我。
如果您使用rm -f
( - force),那么linux将
忽略不存在的文件和参数,从不提示
rm -d will
删除空目录
如果您在提示符处输入rm --help
,则会显示帮助屏幕。最后几行是:
请注意,如果您使用rm删除文件,则可以在给定足够的专业知识和/或时间的情况下恢复其某些内容。为了更好地确保内容真正无法恢复,请考虑使用shred。
由于我的系统已关闭"系统然后我不担心违反安全问题。我的逻辑是,必须有系统密码才能通过SSH连接到操作系统,唯一的用户界面是通过网页。
@ Sliq的评论至今仍然是真实的。你需要根据自己的情况做出决定。