云计算程序员C/C++知识点

惊奇:美国国防部机密文件销毁算法!

2019-01-03  本文已影响150人  Python编程导师

当我们在系统里“删除”了一个文件时,并不意味着这个文件就一定从磁盘上清除了,很多优秀的文件恢复软件都可以恢复被删除的文件,这在一定程度上就带来了隐私泄露的隐患。好在现在很多软件,比如360、电脑管家等等软件都集成了文件粉碎的实用功能。今天介绍一种以前被用于美国国防部的机密文件销毁算法,并附上实现的代码(C)。

算法介绍:

美国国防部DOD5220.22M文件销毁标准包括以下三步:

1.将文件先用0x00覆盖,再用0x01覆盖,如此重复三次;

2.将文件用一个随机值覆盖;

3.将文件名改为一个单字符文件名,最后删除之。

算法可靠性验证:

此算法虽然已经不再被美国国防部采用,但也足够应付一般的环境,主流文件恢复软件恢复的可能性还有待验证。有兴趣和小编一起交流c/c++的可以加小编主页的群哦!下面小编奉上算法代码:

/*

*    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;

}

网友解答:硬件层次还是可以恢复的

为什么需要多次覆盖呢?直观上理解,一次写入后,磁盘上的数据就变化了。其实在硬件层面,不是这样的,还是能够恢复的。恢复的技术有下面两种(Google来的):

第一种是:当硬盘读写头在硬盘上写入一位数据时,它使用的信号强度只是用来写入一位数据,并不会影响到相邻位的数据。由于这个写入信号并不是很强,因此你可以通过它写入的数据位的绝对信号强度来判断此前该数据位所保存的是何种数据。换句话说,如果二进制数据0被二进制数据1所覆盖,其信号强度会比二进制数据1被覆盖要弱一些。使用专门的硬件就可以检测出准确的信号强度。把被覆盖区域读出的信号减去所覆盖数据的标准信号强度,就能获得原先数据的一个副本。更令人吃惊的是,这一恢复过程可以被重复7次!因此如果想避免别人使用这种方法来窃取你的数据,至少要覆盖该数据区域7次,而且每次还应该使用不同的随机数据。

第二种数据恢复技术则是利用了硬盘读写头的另一个特点:读写头每次进行写操作的位置并不一定对得十分精确。这就能让专家们在磁道的边缘侦测到原有的数据(也被称为影子数据)。只有重复地覆写数据才能消除这些磁道边缘的影子数据。

由于硬件的这种特性,在销毁文件的时候,才会需要多次覆盖。

上一篇下一篇

猜你喜欢

热点阅读