Django Tink Fields

Leverages Google Tink to encrypt Django’s core model fields. This work is heavily based on the work of Django Fernet Fields which seems to have been abandoned last few years.

Installation

Use pip to install django-tink-fields:

pip install django-tink-fields

Edit settings.py and introduce a configuration section for TINK_FIELDS_CONFIG:

TINK_FIELDS_CONFIG = {
    "default": {
        "cleartext": False,
        "path": "/path/to/an/encryted_keyset.json",
    },
    "another": {
        "cleartext": True,
        "path": "/path/to/a/cleartext_keyset.json",
    }
}

Tink keysets can be created via tinkey and may optionally be wrapped via a key-management system such as AWS KMS or GCP KMS.

To create a cleartext keyset for testing purposes:

tinkey create-keyset --out-format json --out test_plaintext_keyset.json --key-template AES128_GCM

Alternatively, to create an encrypted keyset that is wrapped by GCP KMS, specify --master-key-uri as follow:

tinkey create-keyset --out-format json --out test_encrypted_keyset.json --key-template AES128_GCM --master-key-uri=gcp-kms://projects/foo1/locations/global/keyRings/foo2/cryptoKeys/foo3

To learn more about tinkey read the relevant documentation.

Examples

The following model creates an encrypted char field that makes use of the default keyset.

from django.db import models
from tink_fields import EncryptedCharField

class SomeModel(models.Model):
    some_value = EncryptedCharField(max_length=32)

You may specify a specific keyset by providing a keyset keyword argument:

from django.db import models
from tink_fields import EncryptedCharField

class AnotherModel(models.Model):
    some_value = EncryptedCharField(max_length=32, keyset="another")

Supported field types include: EncryptedCharField, EncryptedTextField, EncryptedDateField, EncryptedDateTimeField, EncryptedEmailField, and EncryptedIntegerField.

Associated Data

The encrypted fields make use of Authenticated Encryption With Associated Data (AEAD) which offers confidentiality and integrity within the same mode of operation. This allows the caller to specify a cleartext fragment named additional authenticated data (aad) to the encryption and decryption operations and receive cryptographic guarantees that the ciphertext data has not been tampered with.

To specify the aad fragment, provide a callback function aad_callback in the keyword arguments:

from django.db import models
from tink_fields import EncryptedCharField

class AnotherModel(models.Model):
    some_value = EncryptedCharField(max_length=32, aad_callback=lambda x: b"some value")

The value passed to the callback is the instance of the model field, with a signature of Callable[[models.Field], bytes]. As a reminder, the associated data is not encrypted so do not store sensitive data in it.

Acknowledgements

Authors

GitHub

View Github