![]() |
| | #1 |
| Registered User Join Date: May 2009
Posts: 2
| I have developed a portable secure file deletion utility. I want to ask you if you think my approach is enough in terms of ensuring the adequate security. If so, I could extend my application to support recursive directories structures, as well as multiple files selection. Another question would be how to implement secure overwriting of free space on the disc. Can it be done in a portable manner? Even if not, what are my options? Thank you for reading my post! Code: #include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 4 MB buffer */
#define BUFFER_SIZE (4 * 1024 * 1024)
#define MAX_UNSIGNED_CHAR_VAL 255
#define MAX_DELETE_ITERATIONS 32
/* Securely erases a file on the disc, by overwriting,
a given number of times, its content with a random
sequence of bytes. */
int DeleteFile(const char* const fileName, unsigned int overwriteCount)
{
FILE* fileToErase;
long fileSize, filePosition;
unsigned char* buffer;
size_t bytesToWrite;
unsigned int i, j;
if ((fileToErase = fopen(fileName, "rb+")) == NULL)
return -1;
if (overwriteCount > MAX_DELETE_ITERATIONS)
overwriteCount = MAX_DELETE_ITERATIONS;
/* Sets the file stream to be unbuffered */
setbuf(fileToErase, NULL);
/* Determines the file length */
fseek(fileToErase, 0, SEEK_END);
fileSize = ftell(fileToErase);
printf("\nStarting the wipe of file \"%s\" ...\n", fileName);
if (fileSize > 0)
{
/* Allocates the buffer on the heap */
buffer = (unsigned char*)malloc(BUFFER_SIZE * sizeof(unsigned char));
/* Data overwrite iteration */
for (i = 0; i < overwriteCount; i++)
{
/* Initializes the random generator */
srand((unsigned int)time(NULL));
/* Initializes the random buffer */
for (j = 0; j < BUFFER_SIZE; j++)
buffer[j] = (unsigned char)(rand() % (MAX_UNSIGNED_CHAR_VAL + 1));
printf("\nWipe iteration %u ... ", i + 1);
/* Moves the file pointer to the beginning of the file */
fseek(fileToErase, 0, SEEK_SET);
filePosition = 0;
/* Data overwriting block */
while (filePosition < fileSize)
{
if (filePosition + BUFFER_SIZE <= fileSize)
bytesToWrite = BUFFER_SIZE;
else
bytesToWrite = (size_t)(fileSize - filePosition);
fwrite(buffer, sizeof(unsigned char), bytesToWrite, fileToErase);
printf("#");
filePosition += (long)bytesToWrite;
}
printf(" Done\n");
}
free(buffer);
}
fclose(fileToErase);
if (remove(fileName) < 0)
return -2;
return 0;
}
int main(int argc, char** argv)
{
unsigned int iterationsCount;
if ( (argc != 3) || ((iterationsCount = (unsigned int)atoi(argv[2])) == 0) )
{
fprintf(stderr, "\nUsage: wipeit file_path iterations_count\n");
return -1;
}
if (DeleteFile(argv[1], iterationsCount) < 0)
{
fprintf(stderr, "\nCould not delete the file \"%s\".\n", argv[1]);
return -2;
}
printf("\nFile \"%s\" deleted successfully.\n", argv[1]);
return 0;
}
|
| mihnea is offline | |
| | #2 | |
| Senior software engineer Join Date: Mar 2007 Location: Portland, OR
Posts: 5,379
| I didn't look too hard, but it seems okay to me. Quote:
I doubt that will cause every single sector of unallocated space to be overwritten, but portably, it's the best you can do I think.
__________________ "Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot | |
| brewbuck is online now | |
| | #3 |
| and the hat of sweating Join Date: Aug 2007 Location: Toronto, ON
Posts: 3,119
| Why do you call srand() inside your loop? Just call it once in main().
__________________ "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008 |
| cpjust is offline | |
| | #4 |
| Registered User Join Date: May 2009
Posts: 2
| |
| mihnea is offline | |
| | #5 |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,352
| Grr... I already told you elsewhere: go and investigate Eraser.
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way |
| laserlight is offline | |
| | #6 | |
| Ex scientia vera Join Date: Sep 2007
Posts: 426
| Quote:
OT: The FBI and such agencies use some devices that can detect magnetic residue on the hard drives. If write random data over the file, then you take that random data and write the exact opposite of it, e.g. 1010 1010 = Normal 0101 0101 = Opposite You will have flipped the bits. You do this several times, and in theory, this should then only leave magnetic residue that, when "recovered", only gives the random garbage data.
__________________ "What's up, Doc?" "'Up' is a relative concept. It has no intrinsic value." | |
| IceDane is offline | |
| | #7 | |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,352
| Quote:
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | |
| laserlight is offline | |
| | #8 |
| Woof, woof! Join Date: Mar 2007 Location: Australia
Posts: 3,139
| IMO it won't work everywhere, depending on how the "files" are stored. For example with SSDs, again depending on implementation, if the device has wear levelling you might not even end up writing the blocks to where they were in the first place. And thus leaving the original data in the original block (potentially). Also, * Why the cast on malloc() * sizeof(char) is always 1 * There's a few "dangerous" casts * Where's the error checking? :\. i.e. the result of malloc() Last edited by zacs7; 05-05-2009 at 07:28 AM. |
| zacs7 is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| A development process | Noir | C Programming | 30 | 10-28-2009 04:24 AM |
| Memory Address | kevinawad | C++ Programming | 18 | 10-19-2008 10:27 AM |
| Post... | maxorator | C++ Programming | 12 | 10-11-2005 08:39 AM |
| Dikumud | maxorator | C++ Programming | 1 | 10-01-2005 06:39 AM |
| System | drdroid | C++ Programming | 3 | 06-28-2002 10:12 PM |