Always Encrypted с помощью mssql-django

В этой статье объясняется, как использовать SQL Server Always Encrypted с приложениями Django с использованием серверной части mssql-django. Always Encrypted обеспечивает шифрование на уровне столбцов, которое защищает конфиденциальные данные при хранении и передаче.

Необходимые условия

  • Microsoft драйвер ODBC 17 или 18 для SQL Server
  • SQL Server 2016 или более поздней версии или База данных SQL Azure
  • Шифрование столбцов, настроенное на стороне SQL Server (главный ключ столбца и ключ шифрования столбцов)

Принцип работы

Always Encrypted обрабатывается уровнем драйвера ODBC, а не самим Django. При включении ColumnEncryption параметра ODBC драйвер автоматически шифрует и расшифровывает данные по мере передачи между приложением и SQL Server. Модели и запросы Django работают одинаково независимо от того, зашифрованы столбцы или нет.

Хранилище сертификатов Windows

Если главные ключи столбцов хранятся в хранилище сертификатов Windows, включите Always Encrypted, добавив ColumnEncryption=Enabled вextra_params:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "ColumnEncryption=Enabled",
        },
    },
}

Этот подход работает только на Windows.

Azure Key Vault с идентификатором клиента и секретом

Если главные ключи столбцов хранятся в Azure Key Vault, укажите учетные данные приложения вextra_params:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "ColumnEncryption=Enabled;"
                "KeyStoreAuthentication=KeyVaultClientSecret;"
                "KeyStorePrincipalId=<application-client-id>;"
                "KeyStoreSecret=<client-secret>"
            ),
        },
    },
}

Замените <application-client-id> и <client-secret> на идентификатор приложения (клиента) регистрации приложения и значение секрета клиента.

Important

Не прописывайте секреты напрямую в settings.py. Используйте переменные среды или диспетчер секретов для предоставления учетных данных во время выполнения.

Azure Key Vault с управляемым удостоверением

При работе в Azure (например, в Виртуальные машины Azure или Служба приложений Azure) используйте управляемый идентификатор для доступа к Azure Key Vault.

Системно назначенная управляемая идентичность

Дополнительная конфигурация не требуется за пределами KeyStoreAuthentication параметра:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "ColumnEncryption=Enabled;"
                "KeyStoreAuthentication=KeyVaultManagedIdentity"
            ),
        },
    },
}

Управляемая идентификация, назначаемая пользователем

Укажите идентификатор клиента управляемого удостоверения (также называемый идентификатором приложения):

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "ColumnEncryption=Enabled;"
                "KeyStoreAuthentication=KeyVaultManagedIdentity;"
                "KeyStorePrincipalId=<managed-identity-client-id>"
            ),
        },
    },
}

Предоставьте разрешения управляемой идентификации

  1. Предоставьте управляемому удостоверению доступ к базе данных Azure SQL:

    CREATE USER [<identity-name>] FOR EXTERNAL PROVIDER;
    
    ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
    ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];
    
    GRANT VIEW ANY COLUMN MASTER KEY DEFINITION TO [<identity-name>];
    GRANT VIEW ANY COLUMN ENCRYPTION KEY DEFINITION TO [<identity-name>];
    
  2. Предоставьте управляемой идентичности доступ к Azure Key Vault, в котором хранится главный ключ для столбца, с разрешениями, перечисленными в документации по Always Encrypted Azure Key Vault.

Разрешить Django управлять зашифрованными таблицами

При использовании Always Encrypted с Django сначала настройте объекты шифрования на SQL Server, а затем запустите миграцию.

Рекомендуемый порядок:

  1. Создайте главный ключ столбца (CMK) и ключ шифрования столбцов (CEK) на SQL Server или Azure SQL.
  2. Настройте ColumnEncryption=Enabled в параметрах подключения Django.
  3. Выполните миграции Django.
  4. Шифрование целевых столбцов с помощью SQL Server Management Studio или T-SQL.

Выполнение миграций:

python manage.py migrate

mssql-django не создает метаданные ключа Always Encrypted или управляет ими. Политика создания ключей и шифрования столбцов остаются SQL Server административными задачами.

Неподдерживаемые методы проверки подлинности

Аутентификация по имени пользователя и паролю и интерактивная аутентификация Azure Key Vault не поддерживаются для доступа функции Always Encrypted к хранилищу ключей.