Tools to Capture and Convert the Web

How to protect the content of captures?

Encrypted Captures

In the age of laws such as the General Data Protection Regulation, or GDPR protecting user's information has become more important than ever. When a capture is taken it is cached for a short time on our servers to enable it to be downloaded. While our servers are secure and we don’t inspect a user’s captures without permission. This is not enough protection in some scenarios when handling personal information.

The first potential improvement is to no longer cache captures by changing the cache length to zero minutes, on your account page. Note however, this will mean that the capture will not be available to download for very long so must be downloaded immediately after it is created.

Another possible security concern is the actual process of sending the sensitive data to us. In order to secure this data you should first enable SSL, then once we receive the data and it is processed, which happens quite quickly, it will be automatically deleted from our system to ensure there is no security breach.

More security can also be added to PDF or DOCX captures by password protecting the documents. This ensures that only those users with the correct password can access a protected file.

However, if you are capturing very sensitive information such as hospital records etc and want an extra level of protection you can encrypt the resulting captures themselves. To do this you specify an encryption key with each request, these keys are not stored by GrabzIt. This key be used to encrypt the capture protecting the information. As we don't store the key we can't help you recover encrypted captures. Once you receive the capture use the key you generated earlier to decrypt it.

In the example below a cryptographically secure key is created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result.

GrabzItClient grabzIt = new GrabzItClient("Sign in to view your Application Key", "Sign in to view your Application Secret");
grabzIt.UseSSL(true);

string encryptionKey = grabzIt.CreateEncryptionKey();

ImageOptions options = new ImageOptions();
options.EncryptionKey = encryptionKey;

grabzIt.URLToImage("http://www.spacex.com", options);
GrabzItFile encryptedCapture = grabzIt.SaveTo();

GrabzItFile decryptedCapture = grabzIt.Decrypt(encryptedCapture, encryptionKey);

In the example below a cryptographically secure key is created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result.

In order to use encrypted captures with Java 6, 7 and 8 please install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files into all of the /jre/lib/security/ folders of the Java installation folders.

GrabzItClient grabzIt = new GrabzItClient("Sign in to view your Application Key", "Sign in to view your Application Secret");
grabzIt.UseSSL(true);

String encryptionKey = grabzIt.CreateEncryptionKey();

ImageOptions options = new ImageOptions();
options.setEncryptionKey(encryptionKey);

grabzIt.URLToImage("http://www.spacex.com", options);
GrabzItFile encryptedCapture = grabzIt.SaveTo();

GrabzItFile decryptedCapture = grabzIt.Decrypt(encryptedCapture, encryptionKey);

In the example below a cryptographically secure key is automatically created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result automatically by passing true to the DataURI method, which can then be read in the callback method.

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@grabzit/js@3.5.2/grabzit.min.js"></script>
</head>
<body>
<img id="capture"></img>
function callback(dataUri)
{
    document.getElementById('capture').src = dataUri;
}
<script type="text/javascript">
GrabzIt("Sign in to view your Application Key").UseSSL().Encrypt().ConvertURL("http://www.spacex.com").DataURI(callback, true);
</script>
</body>
</html>

In the example below a cryptographically secure key is created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result.

var grabzit = require('grabzit');

var client = new grabzit("Sign in to view your Application Key", "Sign in to view your Application Secret");
client.use_ssl(true);

var encryptionKey = client.create_encryption_key();

client.url_to_image("http://www.spacex.com", {"encryptionKey":encryptionKey});
client.save_to(null, function (error, result){
    if (error != null){
        throw error;
    }
    var decryptedBytes = client.decrypt(result, encryptionKey);
}); 	

Unfortunately Perl can't decrypt AES encryption natively and requires external executables or C compilation. Therefore we haven't added this functionality to our Perl API instead you can add this functionality yourself by using the guide below.

$grabzIt = GrabzItClient->new("Sign in to view your Application Key", "Sign in to view your Application Secret");
$grabzIt->UseSSL(1);

$options = GrabzItImageOptions->new();
$options->encryptionKey("UUK2Xo9OLT2dFvN0wPBGOMZRYqD6WxqFtrZK9YrG+Hg=");
$grabzIt->URLToImage("http://www.spacex.com", $options);
//needs to be decrypted
$data = $grabzIt->SaveTo();

In the example below a cryptographically secure key is created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result.

$grabzIt = new \GrabzIt\GrabzItClient("Sign in to view your Application Key", "Sign in to view your Application Secret");
$grabzIt->UseSSL(true);

$encryptionKey = $grabzIt->CreateEncryptionKey();

$options = new \GrabzIt\GrabzItImageOptions();
$options->setEncryptionKey($encryptionKey);

$grabzIt->URLToImage("http://www.spacex.com", $options);
$encryptedData = $grabzIt->SaveTo();

$decryptedData = $grabzIt->Decrypt($encryptedData, $encryptionKey);

In the example below a cryptographically secure key is created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result.

grabzIt = GrabzItClient.GrabzItClient("Sign in to view your Application Key", "Sign in to view your Application Secret")
grabzIt.UseSSL(True)

encryptionKey = grabzIt.CreateEncryptionKey()

options = GrabzItImageOptions.GrabzItImageOptions()
options.encryptionKey = encryptionKey

grabzIt.URLToImage("http://www.spacex.com", options)
encryptedData = grabzIt.SaveTo()

decryptedData = grabzIt.Decrypt(encryptedData, encryptionKey)

In the example below a cryptographically secure key is created and sent to GrabzIt, this is then used to encrypt the capture. This same encryption key is then used to decrypt the result.

grabzIt = GrabzIt::Client.new("Sign in to view your Application Key", "Sign in to view your Application Secret")
grabzIt.use_ssl(true)

encryptionKey = grabzIt.create_encryption_key()

options = GrabzIt::ImageOptions.new()
options.encryptionKey = encryptionKey

grabzIt.url_to_image("http://www.spacex.com", options)
encryptedData = grabzIt.save_to()

decryptedData = grabzIt.decrypt(encryptedData, encryptionKey)

How GrabzIt's capture encryption works

This guide is very technical and aims to help developers understand how our encryption works. It should be of particular use to Perl developers, as the language doesn't have a open source Perl package that doesn't require completion or installation of third party tools like Open SSL.

Encrypted captures uses 256 bit Advanced Encryption Standard (AES) encryption. It also uses a Cipher Block Chaining (CBC) block cipher mode of operation.

For GrabzIt to encrypt a capture a base 64 encryption key that 44 characters long needs to be passed to the option object. To create this encryption key you should choose 32 random cryptographically secure bytes. These should then be encoded to base 64. As they are cryptographically secure bytes they will be difficult to predict and therefore harder to crack.

When GrabzIt receives a capture request with a encryption key, the capture is encrypted and the initialization vector (IV) is inserted at the beginning of the file. This IV is 16 bytes long and needs to be removed from the front of the file before decryption. The IV must also be passed to the AES algorithm to enable decrypting. When a capture is encrypted no padding is added to the file so when decrypting padding needs to be disabled.

Remember if you have created an improvement to one of our existing client API's or for a entirely new language you can share it with the community through github.