以下是在 *NIX 系统中粉碎文件的安全方法:
碎纸机
#!/bin/bash
# Define number of rewrites
COUNT=20
# Define file size
FILE_SIZE=`wc -c < "$1"`
# Begin rewriting file
while [ $COUNT -ge 0 ]
do
# Write random data to file
echo `dd if=/dev/urandom bs=1 count="$FILE_SIZE"` > $1
COUNT=$(( $COUNT - 1 ))
done
文件是否在正确的偏移量(起点)处被重写?
有没有更短、更好、更便携的方法呢?
答案1
不,相差甚远。
你想要做的事情是不可能的,所以你失败也就不足为奇了。最严重的问题是您甚至没有尝试覆盖文件:… > $1
首先截断文件,这将其所有块标记为空闲,然后命令的输出写入新分配的块。新分配的块没有理由是刚刚从文件中分配的块。
如果你跑的dd if=/dev/urandom bs=1 count="$FILE_SIZE" of="$1"
话就能克服这个障碍。您可以确定您已覆盖该文件的此副本。但该文件的其他副本可能存在于其他地方,例如:
- 生成或编辑文件时创建的临时副本。
- 旧版本(如果文件在过去被编辑过)。
- 任何有权访问该文件的人都可能进行的备份。
- 文件系统快照中存在的其他副本。
- 可能在存储设备内制作的其他副本。在 SSD 上,擦除是一项昂贵的操作(无论是在速度方面还是在设备磨损方面),因此从扇区写入新内容实际上只是将扇区标记为稍后删除,并将数据写入另一个扇区。
擦除数据的安全方法是从第一天起就对整个磁盘进行加密。然后,为了确保数据不可恢复,您只需要擦除密钥即可,密钥通常存储在明确定义的位置。最好根本不要将实际密钥存储在磁盘上:如果机器在人为干预下启动,请使用强密码;如果密钥在没有人为干预的情况下启动,请将密钥存储在智能卡或廉价的 USB 密钥或 SD 卡上,您可以毫不犹豫地物理销毁它们。
请注意,如上所述,如果攻击者具有硬件访问权限或可以破解 SSD 的固件,则仅覆盖 SSD 上的数据并不能保证使其无法恢复。您需要使用 SSD 的安全擦除功能,假设它具有有效的功能(遗憾的是,某些 SSD 型号声称具有该功能,但实际上并没有擦除数据)。
答案2
您的脚本做出的假设不一定正确:
- 覆盖文件的一部分会将新数据写入旧扇区
- 对于 SSD 来说尤其如此(查找磨损均衡)
- 您不使用写入副本或覆盖文件系统(如 btrfs 或 aufs)
编辑:以上内容仅应被视为脚本中问题的粗略列表。尽管我对安全问题并不完全无知,但这里没有处理很多情况,例如编辑文件时的临时副本、将其发送到远程服务器、不同的缓存、交换空间、日志以及许多其他我不知道的事情的。
可能的对策(并非(总是)100%安全):
- 使用 shred,但不适用于 SSD 等基于闪存的介质,也不适用于所有文件系统,包括 ext3 等常见文件系统
- 使用 SSD 制造商提供的工具可能不可用
- 在保存文件之前使用全盘加密,并且对于操作系统分区、交换分区、每个其他分区可能会写入一个(临时)副本,最好也每个其他 HDD/USB 记忆棒/...。将除要删除的文件之外的所有其他数据备份到加密驱动器,然后重新格式化并重新加密与该文件接触的所有介质(包括操作系统分区),并将其他数据放回磁盘上。