Shred(path)
function that overwrites any given file 3 times with random data, and deletes the file afterwards.
The module shred.go
contains the function Shred(path)
which overwrites the given file with random data obtained using the module crypto/rand
, flushing the file, closing it, and reopening it to perform these actions 2 more times.
I've decided to use the module bufio
for buffered writing, as well as using a randomization block size of 4KB. By using these two techniques I've managed to improve speed performance and also reduce the memory footprint.
I've implemented test cases for Shred(path)
which includes:
- testing the
path
parameter for other than a regular file - testing the byte contents to be randomized before deletion
- testing for correct file deletion after randomization
I've included shred_test.go
module for test coverage, which gives the following results:
pablo@machine:~/shred$ go test -v -cover
=== RUN TestShredDir
--- PASS: TestShredDir (0.00s)
=== RUN TestShredNothing
--- PASS: TestShredNothing (0.00s)
=== RUN TestShredRegularFile
--- PASS: TestShredRegularFile (0.00s)
=== RUN TestOverwriteRegularFile
--- PASS: TestOverwriteRegularFile (0.00s)
PASS
coverage: 93.8% of statements
ok github.com/pabloandresm/shred 0.005s
The main use case of Shred(path)
function is security, so if you delete a file with this function, it will be useless if undeleted.
- The main drawback using this function is speed:
- Since the file is overwritten 3 times, then its size will impact duration.
- Since the file could be located on different media types (HDD, SSD, network shares, flash drives), then that technology will impact duration.
- Another drawback could be free storage space. Some filesystems support the sparse feature, which means that the blocks with no data (zeros) are not physically allocated. By using
Shred(path)
the entire size of the file will be allocated before being deleted, which can lead to no free space before completing the task. - If the function is used on a file located on a solid state device, then it will not succeed in hidding its content. This is because of the wear-level mechanisms that these type of devices use, which will translate and hide the mapping between a logical block to a physical one. So after shredding a file, if you read raw blocks from the device you could read content that was supposed to be shredded.
package main
import (
"github.com/pabloandresm/shred"
"fmt"
)
func main() {
//
err := shred.Shred("tmp_file")
if err != nil {
fmt.Println(err)
}
//
}
go get -u github.com/pabloandresm/shred
Pablo Martikian
23 May 2022