Golang : Secure file deletion with wipe example




Problem:

You are not sure if the file deleted by os.Remove() function is good enough to remove your data forever. You have some sensitive data that you do not want the wrong hands to retrieve and you want to securely wipe the file before removing it. How to do that?

Solution:

First, we need to find out how large(size) the file is and create a new slice base on the size filled with 0 value. Use the slice to wipe/replace every single byte in the target file. In this way, we can be sure that the data that we want to remove is wiped clean. The first example is good enough to handle most files.

However, if the target file is big(more than 100MB)...it will use up a lot of available memory and it is not a robust program. To handle a large file, please use the code in example 2.

Here you go!

Example 1:

securedelete.go

 package main

 import (
 "fmt"
 "os"
 )

 func main() {

 var targetFile = "somefile"

 // make sure we open the file with correct permission
 // otherwise we will get the
 // bad file descriptor error
 file, err := os.OpenFile(targetFile, os.O_RDWR, 0666)

 if err != nil {
 panic(err.Error())
 }

 defer file.Close()

 // find out how large is the target file

 fileInfo, err := file.Stat()
 if err != nil {
 panic(err)
 }

 // calculate the new slice size
 // base on how large our target file is

 var size int64 = fileInfo.Size()
 zeroBytes := make([]byte, size)

 // fill out the new slice with 0 value
 copy(zeroBytes[:], "0")
 fmt.Println(zeroBytes[:])

 // wipe the content of the target file
 n, err := file.Write([]byte(zeroBytes))

 if err != nil {
 panic(err)
 }

 fmt.Printf("Wiped %v bytes.\n", n)


 // finally remove/delete our file
 err = os.Remove(targetFile)

 if err != nil {
 panic(err)
 }

 }

To delete a large file, it is better to process the file chunk by chunk when wiping so that it doesn't consume a lot of memory.

securedeletelargefile.go

 package main

 import (
 "fmt"
 "math"
 "os"
 )

 func main() {

 var targetFile = "bigfile"

 // make sure we open the file with correct permission
 // otherwise we will get the
 // bad file descriptor error
 file, err := os.OpenFile(targetFile, os.O_RDWR, 0666)

 if err != nil {
 panic(err.Error())
 }

 defer file.Close()

 // find out how large is the target file

 fileInfo, err := file.Stat()
 if err != nil {
 panic(err)
 }

 // calculate the new slice size
 // base on how large our target file is

 var fileSize int64 = fileInfo.Size()
 const fileChunk = 1 * (1 << 20) // 1 MB, change this to your requirement

 // calculate total number of parts the file will be chunked into
 totalPartsNum := uint64(math.Ceil(float64(fileSize) / float64(fileChunk)))

 lastPosition := 0

 for i := uint64(0); i < totalPartsNum; i++ {

 partSize := int(math.Min(fileChunk, float64(fileSize-int64(i*fileChunk))))
 partZeroBytes := make([]byte, partSize)

 // fill out the part with zero value
 copy(partZeroBytes[:], "0")

 // over write every byte in the chunk with 0 
 fmt.Println("Writing to target file from position : ", lastPosition)
 n, err := file.WriteAt([]byte(partZeroBytes), int64(lastPosition))

 if err != nil {
 panic(err.Error())
 }

 fmt.Printf("Wiped %v bytes.\n", n)

 // update last written position
 lastPosition = lastPosition + partSize
 }

 // finally remove/delete our file
 err = os.Remove(targetFile)

 if err != nil {
 panic(err)
 }

 }

NOTE:

You need to provide both bigfile and somefile in order to run the codes above. To see if a file is really been securely wiped. Comment out the os.Remove() function and then view the files content after executing the wipe process.

References:

https://www.socketloop.com/tutorials/golang-delete-file

https://socketloop.com/references/golang-os-file-write-writestring-and-writeat-functions-example

https://www.socketloop.com/tutorials/golang-read-binary-file-into-memory

https://www.socketloop.com/tutorials/golang-how-to-split-or-chunking-a-file-to-smaller-pieces

  See also : Golang : Delete files by extension





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement