2013-07-09 382 views
45

我想通過使用PHP刪除文件。我已使用unlink()函數,但我想知道unlink的安全性。文件是否完全從服務器上刪除?我想確保無法恢復文件並將文件從服務器上完全刪除。從服務器完全刪除文件

+1

unlink();安全性由您制定 – Guerra

+3

這與操作系統(如何刪除文件)相關,但是,您可以先截斷(清空)該文件,然後刪除它,這是一個很好的問題。 – 2013-07-09 13:06:29

+0

@Akam不能確保文件被刪除,只有它的長度可能會改變。我建議首先用零填寫,然後刪除,但這也不是100%確定的。 – Voitcus

回答

49

以二進制模式打開文件進行寫入,在整個文件上寫入1,關閉文件,然後取消鏈接。覆蓋文件中的任何數據,因此無法恢復。

個人而言,我會說使用1而不是0作爲1的實際數據,並將始終寫入,其中0可能無法寫入,取決於幾個因素。

編輯:一些思考,並評論閱讀後,我會用一種混合的方法去,這取決於你想要的「如何刪除」的文件是,如果你只是想使它這樣的數據不能恢復,用1覆蓋整個文件的長度,因爲這是很快的,並且破壞數據,這個問題是否會在磁盤上留下一定長度的統一數據,從而推斷出文件被USED存在並給出文件長度,提供重要的法醫信息。簡單地寫隨機數據也不會避免這種情況,就好像該文件周圍的所有驅動器扇區都未觸及,這也會留下法醫跟蹤。

的最佳解決方案保在法醫缺失,模糊處理,對於合理的推諉(再次,這是矯枉過正,但即時加入它用於將它的緣故),覆蓋該文件的整個長度與1的和然後,對於HALF以字節爲單位的文件長度,以隨機長度大小從mt_rand開始,從隨機起點寫入,留下許多不同長度的文件曾經在這個區域,從而產生錯誤的痕跡。 (再次,這是完全矯枉過正的,一般只有連環殺手和中央情報局才需要這樣做,但爲了這樣做,我會加上它)。

+0

好主意,你測試過嗎?覆蓋或截斷到零長度之間的差異是什麼?因爲當你編輯相同的文件操作系統將更新存儲上的索引... – 2013-07-09 13:09:25

+0

截斷爲零長度只會根據文件系統改變元數據/文件表,覆蓋,然後解除鏈接完全破壞磁盤上的數據,確保它不能回來 – bizzehdee

+2

或者讓我們使用'mt_rand()'來編寫隨機數字!順便說一句,你想在php聊天室:) – HamZa

2

由於磁盤上存在一些碎片,文件的某些部分可能會保留,即使文件被完全覆蓋也是可能的。

另一種方式是運行(通過shell_exec())外部程序,即系統特定的。 Here is an example(對於Windows),但是我沒有測試過它。

+0

是正確的,但這並不能真正幫助您實現比*僅僅*取消鏈接更好的安全性。 –

0

你應該做多遍覆蓋微跡。例如,使用美國國防部5220-22.M:「用一個字符覆蓋所有可尋址位置,其補碼,然後一個隨機字符並驗證」(來自killdisk站點)

4

這可能無法解決如何完美刪除文件「用PHP」,但它回答你的問題:「文件是否完全從服務器上刪除?」

在某些情況下,不!(在UNIX/POSIX OS上)。

據有關offical PHP unlink() manual page最高的投票意見,取消鏈接功能確實沒有真正刪除文件,它刪除系統鏈接到該文件的內容!由於文件可以有多個文件名(!)[符號鏈接?],只有在所有文件名解除鏈接時纔會刪除文件。所以,如果你的文件有兩個名字,那麼unlink()不會真的刪除這個文件,除非你取消了兩個文件名的鏈接。親愛的Linux傢伙,如有必要,請在這裏糾正我。

這可能是爲什麼函數被調用取消鏈接()而不是刪除()

這裏的優秀評論的完整報價:

刪除一個大的文件,但看到在自由空間或磁盤使用率的下降沒有增加?使用UNIX或其他POSIX操作系統? 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文件的身體(有一個警告,見下文)。這是簡單的,通常的情況。 但是,對於一個文件來說,在相同或不同的目錄中有幾個名字是完全正確的(請參閱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文件中(IMO)最好的方法:

的方式去真正刪除與PHP文件(在Linux)是使用exec()功能,它執行真正的bash命令(做用bash的東西感覺正確btw)。在這種情況下,該文件test.jpg將做刪除:如何使用rm(刪除)正確例如可以here找到

exec("rm test.jpg); 

更多信息。請注意:PHP需要刪除文件的權利!

UPDATE:不幸的是,linux rm命令如果它有兩個名稱/鏈接,它並不真正刪除該文件。 Look here欲瞭解更多信息。 我會有一個更深入的研究,並給予反饋...

+1

您是否也可以添加一些與用戶*可以*實現他們所尋找的刪除類型的問題有關的信息?你有一些很好的信息,但正如你所指出的那樣,這不是一個完美的答案。只是一個建議! –

+0

@AndrewBarber完成! ;) – Sliq

10

美國政府曾經推薦一個七步抹,磁盤。 1)全'1' 2)全0 3)模式 '01' 4)模式 '10' 5)的隨機圖案 6)全 '1' 7)的隨機圖案,

重新編寫代碼示例,使用像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); 
+5

順便說一下偏執狂 –

+1

+1,法醫專家仍然能夠恢復該文件。但沒關係,我認爲。 – Sliq

+0

嘿,修改代碼而不是'file_put_contents($ handle,$ mask);'將會是'file_put_contents($ filename,$ mask);' –