當我們在系統裡“刪除”了一個檔案時,並不意味著這個檔案就一定從磁碟上清除了,很多優秀的檔案恢復軟體都可以恢復被刪除的檔案,這在一定程度上就帶來了隱私洩露的隱患。好在現在很多軟體,比如360、電腦管家等等軟體都整合了檔案粉碎的實用功能。今天介紹一種以前被用於美國國防部的機密檔案銷燬演算法,並附上實現的程式碼(C)。
演算法介紹:
美國國防部DOD5220.22M檔案銷燬標準包括以下三步:
- 將檔案先用0x00覆蓋,再用0x01覆蓋,如此重複三次;
- 將檔案用一個隨機值覆蓋;
- 將檔名改為一個單字元檔名,最後刪除之。
演算法可靠性驗證:
此演算法雖然已經不再被美國國防部採用,但也足夠應付一般的環境,主流檔案恢復軟體恢復的可能性還有待驗證。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
/* * File Destroyer 檔案安全銷燬 * * Copyright (C) 2015 Chaobs * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * E-mail: chaobs@outlook.com * Blog: www.cnblogs.com/chaobs * * 用法: file-destroyer [filename1] <filename2>... * * 演算法介紹: * 基於美國國防部DOD5220.22M標準進行檔案銷燬,包括以下三步: * (1)將檔案先用0x00覆蓋,再用0x01覆蓋,如此重複三次; * (2)將檔案用一個隨機值覆蓋; * (3)將檔名改為一個單字元檔名,最後刪除之。 * * 演算法可靠性驗證: * 此演算法雖然已經不再被美國國防部採用,但也足夠應付一般的環境,對於主流檔案恢復軟體恢復的可能性還有待驗證。 * */ #include <stdio.h> #include <stdlib.h> #include <time.h> void notice(int i, char *s); /* print short notice */ void wipe(FILE *f, char c); /* core func */ long file_size(FILE *f); /* get the size of a file */ int require(int c, char *s[]); int main(int argc, char *argv[]) { int i, j; char ch; FILE *f; notice(1, argv[0]); if (argc < 2) { /* too few arguments */ notice(2, argv[0]); exit(0); } if (!require(argc, argv)) { fprintf(stderr, "Cancel Operating.\n"); exit(0); /* cancel */ } srand(time(NULL)); /* randomize */ for (i = 1; i < argc; ++i) { /* process each file */ if ((f = fopen(argv[i], "r+b")) == NULL) {/* fail to open file */ fprintf(stderr, "Error when open %s:\n", argv[i]); exit(0); } for (j = 0; j < 3; ++j) { /* DOD5220.22M Step 1 */ wipe(f, 0x00); wipe(f, 0x01); } wipe(f, rand() % 256); /* Step 2 */ if (rename(argv[i], "C")) { /* Step 3*/ fprintf(stderr, "Error when rename %s\n", argv[i]); exit(0); /* XXX:檔名衝突的解決?可以考慮使用tmpnam()嗎?*/ } remove("C"); /* XXX:如果是一個符號連線怎樣保證刪除的是真正的檔案? */ fclose(f); } printf("Done! Destroy %d files\n", argc - 1); return 0; } /* implementation */ void notice(int i, char *s) { if (i == 1) { printf("\nFile Destroyer Copyright (C) 2015 Chaobs\n"); printf("This program comes with ABSOLUTELY NO WARRANTY.\n"); printf("This is free software, and you are welcome to redistribute under certain conditions.\n\n"); } else { fprintf(stderr, "Usage: %s [filename1] <filename2> ...\n", s); } } void wipe(FILE *f, char c) { long i; long len = file_size(f); /*獲得檔案長度*/ for (i = 0; i < len; ++i) fwrite(&c, 1, 1, f); /* overwrite */ } long file_size(FILE *f) { long len; fseek(f, 0, SEEK_END); /* jump to the and of file */ len = ftell(f); fseek(f, 0, SEEK_SET); /* restore */ return len; /*感謝網友冰塵醉*/ } int require(int c, char *s[]) { int i; char ch; for (i = 1; i < c; ++i) { /* FIXME: the comfirm function can make mistakes and * it is not convenient even can't work in some cases. */ printf("Do you want to destroy %s ?(y/n) ", s[i]); ch = getchar(); getchar(); /* '\n' */ if (ch == 'n') return 0; } return 1; } |