django-cryptography Documentation

repository·master·Indexed 19 days ago

https://github.com/georgemarshall/django-cryptography

A library providing primitives for encrypting data within Django models by wrapping the Python Cryptography library. It features an encrypt() helper for model fields, PickledField for complex Python objects, and an EncryptedMixin for existing models. Additionally, it offers a drop-in replacement for Django's native cryptographic primitives using Cryptography as the backend.

Tokens
2.2K
Snippets
10
Records
15
Agent score
64%

What's inside django-cryptography

  1. Overview of django-cryptography

    master

    django-cryptography provides primitives for encrypting data within Django applications by wrapping the Python cryptography library. It offers two primary ways to use it:

    1. Encryption Primitives: A set of tools to easily encrypt data.
    2. Django Replacement: A drop-in replacement for Django's built-in cryptographic primitives, using cryptography as the backend provider.

    Unlike other libraries (such as django-cryptographic-fields or django-crypto-fields), django-cryptography is designed to work easily with custom fields and supports modern Python 3 and Django versions.

  2. Migrate an unencrypted field to an encrypted field

    master

    To transition an existing unencrypted database field to an encrypted field using django-cryptography, you must follow a specific sequence of schema and data migrations to ensure no data loss. The process involves renaming the old field, adding a new encrypted field with the original name, copying the data, and finally removing the old field.

    Migration Workflow

    1. Rename the existing field (Schema): Use migrations.RenameField to add a prefix (e.g., old_) to the current field name.
    2. Add the new encrypted field (Schema): Add a new field using the original name, but wrap the field type with django_cryptography.fields.encrypt().
    3. Copy the data (Data): Use migrations.RunPython to iterate through the model instances and copy values from the old_ field to the new encrypted field. It is highly recommended to provide both forwards and reverse functions to allow for rollbacks.
    4. Remove the old field (Schema): Use migrations.RemoveField to delete the prefixed field once the data migration is verified.

    Example Implementation

    Given a model originally defined as:

    class EncryptedCharModel(models.Model):
        field = models.CharField(max_length=15)

    Follow these steps in your Django migrations:

    # 1. Rename existing field
    migrations.RenameField(
        model_name='encryptedcharmodel',
        old_name='field',
        new_name='old_field',
    )
    
    # 2. Add new encrypted field
    migrations.AddField(
        model_name='encryptedcharmodel',
        name='field',
        field=django_cryptography.fields.encrypt(
            models.CharField(default=None, max_length=15)
        ),
        preserve_default=False,
    )
    
    # 3. Copy data (RunPython)
    def forwards_encrypted_char(apps, schema_editor):
        EncryptedCharModel = apps.get_model("fields", "EncryptedCharModel")
        for row in EncryptedCharModel.objects.all():
            row.field = row.old_field
            row.save(update_fields=["field"])
    
    def reverse_encrypted_char(apps, schema_editor):
        EncryptedCharModel = apps.get_model("fields", "EncryptedCharModel")
        for row in EncryptedCharModel.objects.all():
            row.old_field = row.field
            row.save(update_fields=["old_field"])
    
    migrations.RunPython(forwards_encrypted_char, reverse_encrypted_char)
    
    # 4. Remove old field
    migrations.RemoveField(
        model_name='encryptedcharmodel',
        name='old_field',
    )
  3. Configure CRYPTOGRAPHY_KEY

    master

    Define the key used for encryption. If CRYPTOGRAPHY_KEY is set to None (the default), a key will be automatically derived from Django's SECRET_KEY. If you provide a value, that value will be used directly as the key.

    # Use derived key (default)
    CRYPTOGRAPHY_KEY = None
    
    # Use a specific key
    CRYPTOGRAPHY_KEY = b'your-secret-key-bytes'
  4. Encrypt model fields using the encrypt field wrapper

    master

    To protect sensitive data in your database, wrap a standard Django model field with the encrypt function from django_cryptography.fields. This enables symmetrical encryption that automatically encrypts data when saved and decrypts it when retrieved, allowing for bi-directional data access.

    from django.db import models
    from django_cryptography.fields import encrypt
    
    class MyModel(models.Model):
        name = models.CharField(max_length=50)
        sensitive_data = encrypt(models.CharField(max_length=50))
  5. Encrypt model fields using encrypt()

    master

    To protect sensitive data in a Django database, wrap a standard Django model field with the encrypt() function from django_cryptography.fields. This enables automatic symmetrical encryption when the model is saved and allows for bi-directional data retrieval (decryption) when the field is accessed.

    from django.db import models
    from django_cryptography.fields import encrypt
    
    
    class MyModel(models.Model):
        name = models.CharField(max_length=50)
        sensitive_data = encrypt(models.CharField(max_length=50))