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
+22.3k Golang : Set and Get HTTP request headers example
+14.6k Golang : Basic authentication with .htpasswd file
+16.1k Golang : Test floating point numbers not-a-number and infinite example
+8.1k Golang : Convert word to its plural form example
+7.3k Javascript : Push notifications to browser with Push.js
+5.2k Python : Delay with time.sleep() function example
+22.4k Golang : Round float to precision example
+9.9k Golang : Check a web page existence with HEAD request example
+7.1k Golang : Word limiter example
+11.4k Golang : Convert(cast) float to int