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
Tutorials
+10.9k Golang : Calculate Relative Strength Index(RSI) example
+4.5k JavaScript: Add marker function on Google Map
+29.5k Golang : Get and Set User-Agent examples
+12.5k Swift : Convert (cast) Int or int32 value to CGFloat
+16k Golang : convert string or integer to big.Int type
+21.3k Golang : GORM create record or insert new record into database example
+19.8k Golang : Convert seconds to human readable time format example
+31.9k Golang : Convert []string to []byte examples
+5.1k Golang : How to deal with configuration data?
+8.3k Golang : Another camera capture GUI application with GTK and OpenCV
+6.5k Golang : Derive cryptographic key from passwords with Argon2