At e.GO Mobile, cyber and data security have the highest priority.

In companies large amount of data is generated within self-hosted on-premise systems.

If, for example, magnetic hard drives need to be replaced, it is important to destroy the data contained on them before they leave the company and are disposed of.

To do this, I would like to introduce a small PHP sample script today that can quickly and securely shredder files.

A working version can be found as Gist at GitHub.

Algorithm

The script uses the DoD 5220.22-M algorithm which was published by the US Pentagon in 1995 and improved in 2001.

We will have a focus on the version from 1995, which shredders files in following 3 steps:

  1. overwrite all data with 0 bits (0x00 as byte)
  2. overwrite all data with 1 bits (0xFF as byte)
  3. overwrite all data with random data

Implementation

In the first step we should create a helper function which creates a block:

<?php
// ...

function createBlock(callable $nextChar, int $blockSize = 1024) {
    $block = "";

    for ($i = 0; $i < $blockSize; $i++) {
        $block .= $nextChar();  // do not forget: no += ;-)
    }

    return $block;
}

// ...

The $nextChar is a callback, which only returns 1 single byte.

This pattern makes it possible to return always the same byte for the block or a random one on each call.

Now we can implement a function that overwrites all the bytes:

<?php
// ...

function writeBlocks(resource $fileHandle, callable $nextChar, int $blockSize = 1024) {
    // calculate the number of blocks
    // and use at least 1
    $stat = fstat($fileHandle);
    $fileBlockCount = max(
        1,
        ceil(intval($stat['size']) / $blockSize)
    );

    // we start from the beginning
    if (rewind($fileHandle) === false) {
        // failed
        exit(1);
    }

    for ($i = 0; $i < $fileBlockCount; $i++) {
        $block = createBlock($nextChar);

        if (fwrite($fileHandle, $block) === false) {
            // could not write block to file
            exit(1);
        }

        if (fflush($fileHandle) === false) {
            // could not flush block to file
            exit(1);
        }
    }
}

// ...

In this function we submit the file handle from fopen() and the $nextChar function which we will use with createBlock().

Usage

<?php
// ...

// open file with read and write permission
$f = fopen("path/to/my/file.txt", "r+");

// first overwrite with 0 bits (0x00) ...
writeBlocks($f, function() {
    return chr(0);
});
// ... then with 1 bits (0xFF) ...
writeBlocks($f, function() {
    return chr(255);
});
// ... finally with random bytes
writeBlocks($f, function() {
    return mt_rand(0, 255);
});

fclose($f);

// ...

Conclusion

No rocket science as usual 😎

If you need a more secure version, you should use the version from 2001 which needs 7 steps for each file:

  1. overwrite all data with 0 bits (0x00 as byte)
  2. overwrite all data with 1 bits (0xFF as byte)
  3. overwrite all data with random data
  4. overwrite all data with 0 bits (0x00 as byte)
  5. overwrite all data with 0 bits (0x00 as byte)
  6. overwrite all data with 1 bits (0xFF as byte)
  7. overwrite all data with random data

And keep in mind: This algorithm makes no sense with SSDs, because they store their data completly different as magetical discs!

Have fun while trying it out and be very very careful of course!!! 😉