9

如何使用 python 安全地删除文件?该功能os.remove(path)仅删除目录条目,但我想安全地删除文件,类似于随机覆盖文件的名为“Secure Empty Trash”的苹果功能。

什么功能使用这种方法安全地删除文件?

4

5 回答 5

13

您可以使用srm安全地删除文件。您可以使用 Python 的os.system()函数来调用 srm。

于 2013-07-03T18:13:42.603 回答
6

你可以使用srm,当然,你总是可以很容易地在 Python 中实现它。有关用于覆盖文件内容的数据,请参阅维基百科。请注意,根据实际的存储技术,数据模式可能会有很大差异。此外,如果您的文件位于日志结构文件系统上,甚至位于具有写时复制优化的文件系统上,例如 btrfs,您的目标可能无法从用户空间实现。

完成对用于存储文件的磁盘区域的混搭后,使用 . 删除文件句柄os.remove()

如果您还想擦除文件名的任何痕迹,您可以尝试在同一目录中分配和重新分配一大堆随机命名的文件,尽管取决于目录 inode 结构(线性、btree、散列等),它可能很难保证您实际上覆盖了旧文件名。

于 2013-07-03T18:40:35.937 回答
6

你可以很容易地在 Python 中编写一个函数来用随机数据覆盖文件,甚至重复,然后删除它。像这样的东西:

import os

def secure_delete(path, passes=1):
    with open(path, "ba+") as delfile:
        length = delfile.tell()
    with open(path, "br+") as delfile:
        for i in range(passes):
            delfile.seek(0)
            delfile.write(os.urandom(length))
    os.remove(path)

然而,出击srm可能会更快。

于 2013-07-03T18:21:32.983 回答
1

所以至少在 Python 3 中使用@kindall 的解决方案我只是把它追加了。这意味着文件的全部内容仍然完好无损,并且每次传递都只是添加到文件的整体大小中。所以它最终变成了[原始内容][那个大小的随机数据][那个大小的随机数据][那个大小的随机数据],这显然不是想要的效果。

不过,这个诡计对我有用。我在追加中打开文件以查找长度,然后在 r+ 中重新打开,以便我可以寻找开头(在追加模式下,导致不良效果的原因似乎是实际上不可能寻找到 0)

所以检查一下:

def secure_delete(path, passes=3):
with open(path, "ba+", buffering=0) as delfile:
    length = delfile.tell()
delfile.close()
with open(path, "br+", buffering=0) as delfile:
    #print("Length of file:%s" % length)
    for i in range(passes):
        delfile.seek(0,0)
        delfile.write(os.urandom(length))
        #wait = input("Pass %s Complete" % i)
    #wait = input("All %s Passes Complete" % passes)
    delfile.seek(0)
    for x in range(length):
        delfile.write(b'\x00')
    #wait = input("Final Zero Pass Complete")
os.remove(path) #So note here that the TRUE shred actually renames to file to all zeros with the length of the filename considered to thwart metadata filename collection, here I didn't really care to implement

取消注释每次通过后检查文件的提示,当我测试它时看起来不错,但需要注意的是文件名没有像真正的 shred -zu 那样被粉碎

于 2019-02-26T16:38:35.247 回答
0

实施手动解决方案的答案对我不起作用。我的解决方案如下,它似乎工作正常。

import os

def secure_delete(path, passes=1):
    length = os.path.getsize(path)
    with open(path, "br+", buffering=-1) as f:
        for i in range(passes):
            f.seek(0)
            f.write(os.urandom(length))
        f.close()
于 2021-07-20T07:28:54.610 回答