Easily add encryption to your DataObjects. In a time of GDPR and data leaks, this module helps you to keep your data secure.
This module use ciphersweet under the hood to encrypt field data
Thanks to CipherSweet, your encrypted data is searchable!
NOTE: this module is not compatible with previous versions. Please use branch 1 if you need the previous encryption system.
First of all, you need to define an encryption key as part of your environment. This can be done like so in your .env
file:
ENCRYPTION_KEY='here_is_my_key'
You can generate a key with EncryptHelper::generateKey()
.
Make sure your key stays safe and that nobody gets access to it
You define encrypted field types. By default, everything is stored as text (varchars or texts). This is easier since our encrypted
data is in text format.
class MySecureObject extends DataObject
{
use HasEncryptedFields;
private static $db = [
"Name" => 'Varchar',
"MyText" => EncryptedDBText::class,
"MyHTMLText" => EncryptedDBHTMLText::class,
"MyVarchar" => EncryptedDBVarchar::class,
"MyNumber" => EncryptedNumberField::class,
"MyIndexedVarchar" => EncryptedDBField::class,
];
private static $indexes = [
'MyIndexedVarcharBlindIndex' => true,
'MyNumberBlindIndex' => true,
'MyNumberLastFourBlindIndex' => true,
];
public function getField($field)
{
return $this->getEncryptedField($field);
}
public function setField($fieldName, $val)
{
return $this->setEncryptedField($fieldName, $val);
}
}
There are two types of fields : simple and indexes (based on Composite field).
The value is encoded before write
and is decoded when getField
(or any __get) is called.
This is why we have to use the HasEncryptedFields trait, in order to transparently encode and decode data.
Otherwise, we end up loading encrypted data from the database that is never decoded if you don't
use dbObject calls.
You can of course not use the trait, just keep in mind that your calls to $myObject->myEncryptedField = 'my value'
won't be encoded automatically. But you can most certainly do $myObject->dbObject('myEncryptedField')->setValue('my value') ...
but that's really not convenient in my opinion.
Maybe I'll find some way to avoid overriding the get/set field methods, but I haven't been succesful so far.
This module provides three fields without blind indexes (if you need a blind index, see next point):
These fields work exactly like their regular counterpart, except the data is encrypted.
Thanks to CipherSweet, data is encrypted with a blind index. This blind index can be used to search data if you know the value
or a partial value based on what kind of index you created.
To search using an index, use the EncryptedDBField instance
$singl = singleton(MyModel::class);
$obj = $singl->dbObject('MyEncryptedField');
$searchValue = $obj->getSearchValue($value);
$query = MyModel::get()->where(array('MyEncryptedFieldBlindIndex = ?' => $searchValue));
Or use shortcut
$singl = singleton(MyModel::class);
$obj = $singl->dbObject('MyEncryptedField');
$record = $obj->fetchRecord($value);
Or use search filter
$record = MyModel::get()->filter('MyEncryptedField:Encrypted', $searchValue)->first();
It is highly recommended to set indexes on your fields that use blind indexes. The convention is as follows:
{Name}BlindIndex and {Name}LastFourBlindIndex
This module provides two fields with blind indexes:
You can extend EncryptedDBField
to add more fields types to suit your use case.
You can also encrypt and decrypt data using a symmetrical key with the helper
$someText = 'some text';
$encrypt = EncryptHelper::encrypt($someText);
$decryptedValue = EncryptHelper::decrypt($encrypt);
This module automatically adds EncryptedDBFile
extension to your files.
This will add an Encrypted
field in your table that tracks encryption status
Please note that files are not encrypted by default, you need to call
$myFile->encryptFileIfNeeded();
After your uploads, for example.
Even if your files are encrypted, they should not be available in your public folder.
Make sure to review SilverStripe file security documentation.
Keeping files .protected and served by a dedicated controller (using sendDecryptedFile
) is necessary.
Tested with 4.6 but should work with 4.4+
LeKoala - [email protected]
Module rating system helping users find modules that are well supported. For more on how the rating system works visit Module standards
Score not correct? Let us know there is a problem