Click here to Skip to main content
15,867,756 members
Articles / Programming Languages / C#
Article

Securely Delete a File using .NET

Rate me:
Please Sign up or sign in to vote.
4.71/5 (27 votes)
14 Jan 2008CPOL2 min read 121.5K   4.9K   68   29
How to securely delete a file using .NET

Introduction

This is an attempt to make it a little more secure to delete files using C#. Let's face it: using File.Delete doesn't really delete the file; it just makes the OS think that the file doesn't exist. The space on the disc that the file occupied is marked as free and available for writing, but the file's data is not removed and can be recovered quite easily. The file is not gone until the space it occupied is overwritten, preferably several times.

I have put together a simple class that can be used to accomplish the procedure of writing garbage data to the file before deleting it. To take it a step further, I truncate the file to 0 bytes and change the file-dates. However, the step to change the file dates only seems to work on FAT 16/32 and not NTFS. After running several tests with Ontrack EasyRecovery, PC Inspector File Recovery and GetDataBack, I could not recover any of the files. I even ran Disk Investigator after deleting a text-file, checking the individual clusters, and I couldn't get a single word back from the file.

Background

The background to this project is simple. After using file-wipers/shredders for years now, I wanted to see what could be accomplished with .NET.

Using the Code

There is only one method that you need to call, namely WipeFile and the code is as shown below. So, all you really have to do is call WipeFile and supply the full path of the file to be deleted, as well as the number of times you want to overwrite it.

C#
public void WipeFile(string filename, int timesToWrite)
{
    try
    {
        if (File.Exists(filename))
        {
            // Set the files attributes to normal in case it's read-only.

            File.SetAttributes(filename, FileAttributes.Normal);

            // Calculate the total number of sectors in the file.
            double sectors = Math.Ceiling(new FileInfo(filename).Length/512.0);

            // Create a dummy-buffer the size of a sector.

            byte[] dummyBuffer = new byte[512];

            // Create a cryptographic Random Number Generator.
            // This is what I use to create the garbage data.

            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            // Open a FileStream to the file.
            FileStream inputStream = new FileStream(filename, FileMode.Open);
            for (int currentPass = 0; currentPass < timesToWrite; currentPass++)
            {
                UpdatePassInfo(currentPass + 1, timesToWrite);

                // Go to the beginning of the stream

                inputStream.Position = 0;

                // Loop all sectors
                for (int sectorsWritten = 0; sectorsWritten < sectors; sectorsWritten++)
                {
                    UpdateSectorInfo(sectorsWritten + 1, (int) sectors);

                    // Fill the dummy-buffer with random data

                    rng.GetBytes(dummyBuffer);

                    // Write it to the stream
                    inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                }
            }

            // Truncate the file to 0 bytes.
            // This will hide the original file-length if you try to recover the file.

            inputStream.SetLength(0);

            // Close the stream.
            inputStream.Close();

            // As an extra precaution I change the dates of the file so the
            // original dates are hidden if you try to recover the file.

            DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
            File.SetCreationTime(filename, dt);
            File.SetLastAccessTime(filename, dt);
            File.SetLastWriteTime(filename, dt);

            // Finally, delete the file

            File.Delete(filename);

            WipeDone();
        }
    }
    catch(Exception e)
    {
        WipeError(e);
    }
}

I have added some events just to be able to keep track of what's happening during the process.

  • PassInfoEvent - Returns which pass is running and the total number of passes to be run.
  • SectorInfoEvent - Returns which sector is being written to and the total number of sectors to be written to.
  • WipeDoneEvent - An indicator that the wipe process is done.
  • WipeErrorEvent - Returns the exception if anything went wrong.

Acknowledgements

I'd like to thank PIEBALDconsult for his time and help in the forum while working with this.

History

  • 7 January, 2008 -- Original version posted
  • 14 January, 2008 -- First update

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Sweden Sweden
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionThis Software Is Not Working For Wiping Pendrive Data ( 64 Bit) Pin
Member 1271500328-Aug-17 0:12
Member 1271500328-Aug-17 0:12 
PraiseWhats 2037? Pin
Ravior23-Apr-16 2:04
Ravior23-Apr-16 2:04 
PraiseWhats 2037? Pin
Ravior23-Apr-16 2:04
Ravior23-Apr-16 2:04 
Questionyou have a bug when opening the file for write Pin
arielbeck19-Sep-15 23:26
arielbeck19-Sep-15 23:26 
SuggestionFilename wipe Pin
Trophygeek1-Apr-15 9:32
Trophygeek1-Apr-15 9:32 
Questionno.... Pin
Sam Haycraft4-Mar-15 14:07
Sam Haycraft4-Mar-15 14:07 
AnswerRe: no.... Pin
Trophygeek1-Apr-15 9:34
Trophygeek1-Apr-15 9:34 
QuestionVB.NET Equivalent? Pin
FloatingPoint44418-Dec-13 9:08
FloatingPoint44418-Dec-13 9:08 
QuestionWhy do you assume 512-byte sectors? Pin
Yuri Zholobov28-Jan-08 5:14
Yuri Zholobov28-Jan-08 5:14 
AnswerRe: Why do you assume 512-byte sectors? Pin
Johan Martensson28-Jan-08 5:58
Johan Martensson28-Jan-08 5:58 
GeneralRe: Why do you assume 512-byte sectors? Pin
Yuri Zholobov28-Jan-08 20:41
Yuri Zholobov28-Jan-08 20:41 
GeneralRe: Why do you assume 512-byte sectors? Pin
Member 1074926816-Jan-15 9:55
Member 1074926816-Jan-15 9:55 
GeneralNotice about System Resotre Pin
Przemyslaw Celej14-Jan-08 12:55
Przemyslaw Celej14-Jan-08 12:55 
GeneralSome doubts [modified] Pin
Luc Pattyn7-Jan-08 14:55
sitebuilderLuc Pattyn7-Jan-08 14:55 
GeneralRe: Some doubts Pin
PIEBALDconsult7-Jan-08 16:03
mvePIEBALDconsult7-Jan-08 16:03 
GeneralRe: Some doubts Pin
Luc Pattyn7-Jan-08 16:28
sitebuilderLuc Pattyn7-Jan-08 16:28 
GeneralRe: Some doubts Pin
Johan Martensson7-Jan-08 21:04
Johan Martensson7-Jan-08 21:04 
GeneralRe: Some doubts Pin
Luc Pattyn8-Jan-08 2:18
sitebuilderLuc Pattyn8-Jan-08 2:18 
GeneralRe: Some doubts Pin
Johan Martensson8-Jan-08 4:22
Johan Martensson8-Jan-08 4:22 
GeneralWhoops Pin
PIEBALDconsult7-Jan-08 5:13
mvePIEBALDconsult7-Jan-08 5:13 
GeneralRe: Whoops Pin
Johan Martensson7-Jan-08 6:57
Johan Martensson7-Jan-08 6:57 
GeneralVery Nice Pin
merlin9817-Jan-08 4:36
professionalmerlin9817-Jan-08 4:36 
GeneralRe: Very Nice Pin
Johan Martensson7-Jan-08 5:17
Johan Martensson7-Jan-08 5:17 
QuestionFilling the file with 0 would work? Pin
Jcmorin7-Jan-08 3:44
Jcmorin7-Jan-08 3:44 
AnswerRe: Filling the file with 0 would work? Pin
Johan Martensson7-Jan-08 4:03
Johan Martensson7-Jan-08 4:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.