美国国防部机密文件销毁算法
当我们在系统里“删除”了一个文件时,并不意味着这个文件就一定从磁盘上清除了,很多优秀的文件恢复软件都可以恢复被删除的文件,这在一定程度上就带来了隐私泄露的隐患。好在现在很多软件,比如360、电脑管家等等软件都集成了文件粉碎的实用功能。今天介绍一种以前被用于美国国防部的机密文件销毁算法,并附上实现的代码(C)。
算法介绍:
美国国防部DOD5220.22M文件销毁标准包括以下三步:
- 将文件先用0x00覆盖,再用0x01覆盖,如此重复三次;
- 将文件用一个随机值覆盖;
- 将文件名改为一个单字符文件名,最后删除之。
算法可靠性验证:
此算法虽然已经不再被美国国防部采用,但也足够应付一般的环境,主流文件恢复软件恢复的可能性还有待验证。
实现:
• v 0.2.0 修改(这是给不读源码的朋友准备的)
1.修正了file_size()返回值的错误;
2.wipe()函数改为block_wipe(),但是我不知道它是否真的能提高效率。
本人的部分博文已经转移至chaosxie.top,本博客将不再更新,希望您能继续支持我!
1 /* 2 * File Destroyer v 0.2.0 文件安全销毁 3 * 4 * Copyright (C) 2015 Chaobs 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * E-mail: chaobs@outlook.com 20 * Blog: www.cnblogs.com/chaobs 21 * 22 * 用法: file-destroyer [filename1] <filename2>... 23 * 24 * 算法介绍: 25 * 基于美国国防部DOD5220.22M标准进行文件销毁,包括以下三步: 26 * (1)将文件先用0x00覆盖,再用0x01覆盖,如此重复三次; 27 * (2)将文件用一个随机值覆盖; 28 * (3)将文件名改为一个单字符文件名,最后删除之。 29 * 30 * 算法可靠性验证: 31 * 此算法虽然已经不再被美国国防部采用,但也足够应付一般的环境,对于主流文件恢复软件恢复的可能性还有待验证。 32 * 33 * |-------------------------------------------------------------------------------------------| 34 * | v 0.2.0更新: | 35 * | (1)将原有的wipe()改为block_wipe(),block_wipe()采用成块的写入,可以提高程序运行效率。 | 36 * | | 37 * | v 0.1.0更新: | 38 * | (1)修正了file_size()无返回值的问题(感谢网友冰尘醉); | 39 * | (2)将file_zize()的调用移到了循环的外部。 | 40 * |-------------------------------------------------------------------------------------------| 41 */ 42 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <time.h> 46 47 48 void notice(int i, char *s); /* print short notice */ 49 50 /* 51 * v 0.2.0 的 blokc_wipe()一次写入一整块,保证了性能。 52 * core function 53 */ 54 void block_wipe(FILE *f, char c); 55 56 long file_size(FILE *f); /* get the size of a file */ 57 58 int require(int c, char *s[]); 59 60 61 int main(int argc, char *argv[]) 62 { 63 int i, j; 64 65 FILE *f; 66 67 notice(1, argv[0]); 68 69 if (argc < 2) { 70 /* too few arguments */ 71 notice(2, argv[0]); 72 exit(0); 73 } 74 75 if (!require(argc, argv)) { 76 fprintf(stderr, "Cancel Operating.\n"); 77 exit(0); /* cancel */ 78 } 79 80 srand(time(NULL)); /* randomize */ 81 82 for (i = 1; i < argc; ++i) { 83 /* process each file */ 84 85 if ((f = fopen(argv[i], "r+b")) == NULL) {/* fail to open file */ 86 fprintf(stderr, "Error when open %s:\n", argv[i]); 87 exit(0); 88 } 89 90 for (j = 0; j < 3; ++j) { 91 /* DOD5220.22M Step 1 */ 92 /* v 0.2.0 新增*/ 93 block_wipe(f, 0x00); 94 block_wipe(f, 0x01); 95 } 96 97 block_wipe(f, rand() % 256); /* Step 2 */ 98 99 if (rename(argv[i], "C")) { 100 /* Step 3*/ 101 fprintf(stderr, "Error when rename %s\n", argv[i]); 102 exit(0); 103 104 /* XXX:文件名冲突的解决?可以考虑使用tmpnam()吗?*/ 105 } 106 107 remove("C"); /* XXX:如果是一个符号连接怎样保证删除的是真正的文件? */ 108 fclose(f); 109 } 110 111 printf("Done! Destroy %d files\n", argc - 1); 112 113 return 0; 114 } 115 116 117 /* implementation */ 118 119 void notice(int i, char *s) 120 { 121 if (i == 1) { 122 printf("\nFile Destroyer Copyright (C) 2015 Chaobs\n"); 123 printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); 124 printf("This is free software, and you are welcome to redistribute under certain conditions.\n\n"); 125 } else { 126 fprintf(stderr, "Usage: %s [filename1] <filename2> ...\n", s); 127 } 128 } 129 130 void block_wipe(FILE *f, char c) 131 { 132 long len = file_size(f); 133 134 fwrite(&c, sizeof(char), len, f); /* 覆盖,直接一次性写入 */ 135 136 } 137 138 long file_size(FILE *f) 139 { 140 long len; 141 fseek(f, 0, SEEK_END); /* jump to the and of file */ 142 len = ftell(f); 143 fseek(f, 0, SEEK_SET); /* restore */ 144 return len; /*感谢网友冰尘醉*/ 145 } 146 147 148 int require(int c, char *s[]) 149 { 150 int i; 151 char ch; 152 for (i = 1; i < c; ++i) { 153 /* FIXME: the comfirm function can make mistakes and 154 * it is not convenient even can't work in some cases. 155 */ 156 printf("Do you want to destroy %s ?(y/n) ", s[i]); 157 ch = getchar(); 158 getchar(); /* '\n' */ 159 if (ch == 'n') 160 return 0; 161 } 162 163 return 1; 164 }
后记:
这篇博文纯属因为我的一个朋友从图书馆里找到一本老书(书名《TURBO PASCAL高级编程技术与实用程序集锦》,学苑出版社,1994,董占山),上面记录了这个“美国国防部机密文件销毁算法”,我一时觉得好玩就把它用C语言写了下来。我上一次在就说过:
This is free software, and you are welcome to redistribute it under certain conditions.
这也是我在源码前面加了一端GPL申明的原因,希望不要把讨论的焦点从代码本身放到别的问题上。
不要想你能为世界做什么,想想你该为世界做什么!