mssql-django를 사용하여 Always Encrypted

이 문서에서는 Django 애플리케이션에서 mssql-django 백엔드를 통해 SQL Server Always Encrypted를 사용하는 방법을 설명합니다. Always Encrypted는 저장 시 및 전송 중인 민감한 데이터를 보호하는 열 단위 암호화를 제공합니다.

사전 요구 사항

  • Microsoft SQL Server용 ODBC 드라이버 17 또는 18
  • SQL Server 2016 이상 또는 Azure SQL Database
  • SQL Server 쪽에서 구성된 열 암호화(열 마스터 키 및 열 암호화 키)

작동 방식

Always Encrypted는 Django 자체가 아니라 ODBC 드라이버 계층에서 처리됩니다. ODBC 매개 변수를 ColumnEncryption 사용하도록 설정하면 드라이버가 애플리케이션과 SQL Server 간에 전달되는 데이터를 자동으로 암호화하고 암호를 해독합니다. Django 모델 및 쿼리는 열 암호화 여부와 동일한 방식으로 작동합니다.

Windows 인증서 저장소

열 마스터 키가 Windows 인증서 저장소에 저장된 경우 extra_paramsColumnEncryption=Enabled를 추가하여 Always Encrypted를 사용하도록 설정합니다.

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 경우에만 작동합니다.

클라이언트 ID 및 암호를 사용하는 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>을 앱 등록의 애플리케이션(클라이언트) ID 및 클라이언트 암호 값으로 바꿉니다.

Important

settings.py에 비밀 정보를 하드코딩하지 마세요. 환경 변수 또는 비밀 관리자를 사용하여 런타임에 자격 증명을 제공합니다.

관리 ID를 사용한 Azure Key Vault

Azure 실행하는 경우(예: Azure Virtual Machines 또는 Azure App Service) 관리 ID를 사용하여 Azure Key Vault 액세스합니다.

시스템 할당 관리 ID

매개 변수 이외의 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"
            ),
        },
    },
}

사용자가 할당한 관리 ID

관리 ID의 클라이언트 ID(애플리케이션 ID라고도 함)를 포함합니다.

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>"
            ),
        },
    },
}

관리 ID 권한 부여

  1. 관리 ID에 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 설명서에 나열된 사용 권한으로 열 마스터 키를 저장하는 Azure Key Vault 관리 ID에 대한 액세스 권한을 부여합니다.

Django에서 암호화된 테이블을 관리하도록 허용

Django에서 Always Encrypted를 사용하는 경우 먼저 SQL Server 암호화 개체를 구성한 다음 마이그레이션을 실행합니다.

추천 순서:

  1. SQL Server 또는 Azure SQL CMK(열 마스터 키) 및 CEK(열 암호화 키)를 만듭니다.
  2. Django 연결 설정에서 ColumnEncryption=Enabled을 설정합니다.
  3. Django 마이그레이션을 실행합니다.
  4. SQL Server Management Studio 또는 T-SQL을 사용하여 대상 열을 암호화합니다.

마이그레이션 실행:

python manage.py migrate

mssql-django 는 Always Encrypted 키 메타데이터를 만들거나 관리하지 않습니다. 키 생성 및 열 암호화 정책은 여전히 SQL Server 관리 작업입니다.

지원되지 않는 인증 방법

사용자 이름/암호 및 Azure Key Vault 대화형 인증은 Always Encrypted 키 저장소 액세스에 대해 지원되지 않습니다.