Configurar el cifrado de columnas localmente con PowerShell

Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

En este artículo se proporcionan los pasos necesarios para establecer la configuración de destino de Always Encrypted para las columnas de base de datos mediante el cmdlet Set-SqlColumnEncryption (en el módulo SqlServer de PowerShell). El cmdlet Set-SqlColumnEncryption modifica tanto el esquema de la base de datos de destino como los datos almacenados en las columnas seleccionadas. Los datos almacenados en una columna se pueden cifrar, volver a cifrar o descifrar, en función de la configuración de cifrado de destino especificada para las columnas y la configuración de cifrado actual. Para activar operaciones criptográficas locales mediante un enclave, Set-SqlColumnEncryption debe usar una conexión de base de datos creada mediante una cadena de conexión con las palabras clave Protocolo de atestación y, opcionalmente, URL de atestación.

Requisitos previos

Para establecer la configuración de cifrado de destino, debe asegurarse de que:

  • se configura una clave de cifrado de columna con enclave habilitado en la base de datos (si estás cifrando o volviendo a cifrar una columna). Para más detalles, consulte Administrar claves para Always Encrypted con enclaves protegibles.
  • está conectado a la base de datos con Always Encrypted habilitado y las propiedades de atestación especificadas en la cadena de conexión.
  • Puede tener acceso a la clave maestra de columna para cada columna que quiere cifrar, volver a cifrar o descifrar desde el equipo que ejecuta los cmdlets de PowerShell.
  • usted usa la versión 22.0.50 o una posterior del módulo PowerShell de SqlServer. Para el cifrado en línea en el lugar, use la versión 22.3.0 o posterior del módulo SqlServer de PowerShell.

Note

Microsoft recomienda usar PowerShell 7 o posterior al ejecutar scripts de PowerShell de Always Encrypted. PowerShell 7 proporciona compatibilidad multiplataforma mejorada, un mejor rendimiento y la compatibilidad más reciente con el módulo SqlServer (v22+), que es necesario para muchos escenarios de Always Encrypted.

Consideraciones sobre la seguridad

El cmdlet Set-SqlColumnEncryption , que se usa para configurar el cifrado de las columnas de la base de datos, administra las claves de Always Encrypted y los datos almacenados en las columnas de la base de datos. Por esta razón, es importante que ejecute el cmdlet en un equipo seguro. Si la base de datos está en SQL Server, ejecute el cmdlet en un equipo diferente del que hospeda la instancia de SQL Server. Dado que el objetivo principal de Always Encrypted es garantizar la seguridad de la información confidencial cifrada, incluso si el sistema de base de datos está en peligro, la ejecución de un script de PowerShell que procese las claves o la información confidencial en el equipo de SQL Server puede reducir o anular las ventajas de la característica.

Tarea Artículo Accede a claves de texto no cifrado o a almacén de claves Accede a base de datos
Paso 1. Inicie un entorno de PowerShell e importe el módulo SqlServer. Importar el módulo SqlServer No No
Paso 2. Conecte con el servidor y la base de datos. Conexión a una base de datos No
Paso 3. Autentíquese en Azure si la clave maestra de columna (que protege la clave de cifrado de columna que se va a rotar) se almacena en Azure Key Vault. Connect-AzAccount No
Paso 4. Obtenga un token de acceso para Azure Key Vaults. Get-AzAccessToken No No
Paso 5. Construya una matriz de objetos SqlColumnEncryptionSettings, una para cada columna de base de datos que quiera cifrar, volver a cifrar o descifrar. SqlColumnMasterKeySettings es un objeto que existe en memoria (en PowerShell). Especifica el esquema de cifrado de destino de una columna. New-SqlColumnEncryptionSettings No No
Paso 6. Establezca la configuración de cifrado que quiera, especificada en la matriz de objetos SqlColumnMasterKeySettings que creó en el paso anterior. Una columna se cifra, vuelve a cifrar o descifrar, según la configuración de destino especificada y la configuración de cifrado actual de la columna. Set-SqlColumnEncryption

Nota: Este paso puede tardar mucho tiempo. Las aplicaciones no pueden acceder a las tablas durante toda la operación o durante una parte de ella, según el enfoque (en línea o fuera de línea) que seleccione.

Cifrado de columnas mediante enclaves de VBS

En el ejemplo siguiente se muestra cómo establecer la configuración de cifrado de destino de un par de columnas. Si alguna de las columnas todavía no está cifrada, se cifrará. Si una columna ya está cifrada con una clave diferente o con un tipo de cifrado diferente, se descifrará y se volverá a cifrar con la clave o el tipo de destino especificados. Actualmente, los enclaves de VBS no admiten la atestación. El parámetro EnclaveAttestationProtocol debe establecerse en None y EnclaveAttestationUrl no es necesario.

# Import modules
Import-Module SqlServer
Import-Module Az.Accounts

# Edit these values.
$serverName = '<your-server>.database.windows.net'
$databaseName = 'ContosoHR'
$cekName = 'CEK'
$subscriptionId = '<your-subscription-id>'

# Columns to encrypt with the CEK.
$columnsToEncrypt = @(
    'dbo.Employees.SSN',
    'dbo.Employees.Salary'
)

# Sign in with Microsoft Entra and select subscription.
Connect-AzAccount
Set-AzContext -SubscriptionId $subscriptionId

# Token needed when CEK uses Azure Key Vault CMK.
$keyVaultAccessToken = (Get-AzAccessToken -ResourceUrl 'https://vault.azure.net').Token

# Connect to Azure SQL Database using Entra auth.
$connStr = "Server=tcp:$serverName,1433;Database=$databaseName;Encrypt=True;TrustServerCertificate=False;Authentication=Active Directory Interactive"
$database = Get-SqlDatabase -ConnectionString $connStr

# Build encryption settings for target columns.
$columnEncryptionSettings = @(
    $columnsToEncrypt | ForEach-Object {
        New-SqlColumnEncryptionSettings -ColumnName $_ -EncryptionType Randomized -EncryptionKey $cekName
    }
)

# Encrypt or re-encrypt the columns.
Set-SqlColumnEncryption -InputObject $database -ColumnEncryptionSettings $columnEncryptionSettings -EnclaveAttestationProtocol None -LogFileDirectory . -KeyVaultAccessToken $keyVaultAccessToken

Write-Host 'Done.'

Descifrado de columnas: ejemplo

En el ejemplo siguiente se muestra cómo descifrar todas las columnas que actualmente están cifradas en una base de datos.

# Import modules
Import-Module SqlServer -MinimumVersion 22.0.50
Import-Module Az.Accounts -MinimumVersion 2.2.0

#Connect to Azure
Connect-AzAccount

# Obtain an access token for key vaults.
$keyVaultAccessToken = (Get-AzAccessToken -ResourceUrl https://vault.azure.net).Token  

# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Connect to Azure SQL Database using Entra auth.
$connStr = "Server=tcp:$serverName,1433;Database=$databaseName;Encrypt=True;TrustServerCertificate=False;Authentication=Active Directory Interactive"
$database = Get-SqlDatabase -ConnectionString $connStr

# Find all encrypted columns, and create a SqlColumnEncryptionSetting object for each column.
$ces = @()
$tables = $database.Tables
for($i=0; $i -lt $tables.Count; $i++){
    $columns = $tables[$i].Columns
    for($j=0; $j -lt $columns.Count; $j++) {
        if($columns[$j].isEncrypted) {
            $threeColPartName = $tables[$i].Schema + "." + $tables[$i].Name + "." + $columns[$j].Name 
            $ces += New-SqlColumnEncryptionSettings -ColumnName $threeColPartName -EncryptionType "Plaintext" 
        }
    }
}

# Decrypt all columns.
Set-SqlColumnEncryption -ColumnEncryptionSettings $ces -InputObject $database -LogFileDirectory . -EnclaveAttestationProtocol "None" -KeyVaultAccessToken $keyVaultAccessToken

Cifrado de columnas mediante enclaves SGX

En el ejemplo siguiente se muestra cómo establecer la configuración de cifrado de destino de un par de columnas. Si alguna de las columnas todavía no está cifrada, se cifrará. Si una columna ya está cifrada con una clave diferente o con un tipo de cifrado diferente, se descifrará y se volverá a cifrar con la clave o el tipo de destino especificados. Para activar operaciones criptográficas locales mediante un enclave, se requieren los parámetros EnclaveAttestationProtocol y EnclaveAttestationUrl.

# Import modules
Import-Module SqlServer
Import-Module Az.Accounts

# Edit these values.
$serverName = '<your-server>.database.windows.net'
$databaseName = 'ContosoHR'
$cekName = 'CEK'
$subscriptionId = '<your-subscription-id>'

# Columns to encrypt with the CEK.
$columnsToEncrypt = @(
    'dbo.Employees.SSN',
    'dbo.Employees.Salary'
)

# Sign in with Microsoft Entra and select subscription.
Connect-AzAccount
Set-AzContext -SubscriptionId $subscriptionId

# Token needed when CEK uses Azure Key Vault CMK.
$keyVaultAccessToken = (Get-AzAccessToken -ResourceUrl 'https://vault.azure.net').Token

# Connect to Azure SQL Database using Entra auth.
$connStr = "Server=tcp:$serverName,1433;Database=$databaseName;Encrypt=True;TrustServerCertificate=False;Authentication=Active Directory Interactive"
$database = Get-SqlDatabase -ConnectionString $connStr

# Build encryption settings for target columns.
$columnEncryptionSettings = @(
    $columnsToEncrypt | ForEach-Object {
        New-SqlColumnEncryptionSettings -ColumnName $_ -EncryptionType Randomized -EncryptionKey $cekName
    }
)
# Encrypt or re-encrypt the columns.
Set-SqlColumnEncryption -InputObject $database -ColumnEncryptionSettings $columnEncryptionSettings -EnclaveAttestationProtocol "AAS" -EnclaveAttestationURL "https://<attestationURL>"   -KeyVaultAccessToken $keyVaultAccessToken -LogFileDirectory .

Write-Host 'Done.' 

Descifrado de columnas: ejemplo

En el ejemplo siguiente se muestra cómo descifrar todas las columnas que actualmente están cifradas en una base de datos.

# Import modules
Import-Module "SqlServer" -MinimumVersion 22.0.50
Import-Module Az.Accounts -MinimumVersion 2.2.0

#Connect to Azure
Connect-AzAccount

# Obtain an access token for key vaults.
$keyVaultAccessToken = (Get-AzAccessToken -ResourceUrl https://vault.azure.net).Token  

# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Connect to Azure SQL Database using Entra auth.
$connStr = "Server=tcp:$serverName,1433;Database=$databaseName;Encrypt=True;TrustServerCertificate=False;Authentication=Active Directory Interactive"
$database = Get-SqlDatabase -ConnectionString $connStr

# Find all encrypted columns, and create a SqlColumnEncryptionSetting object for each column.
$ces = @()
$tables = $database.Tables
for($i=0; $i -lt $tables.Count; $i++){
    $columns = $tables[$i].Columns
    for($j=0; $j -lt $columns.Count; $j++) {
        if($columns[$j].isEncrypted) {
            $threeColPartName = $tables[$i].Schema + "." + $tables[$i].Name + "." + $columns[$j].Name 
            $ces += New-SqlColumnEncryptionSettings -ColumnName $threeColPartName -EncryptionType "Plaintext" 
        }
    }
}

# Decrypt all columns.
Set-SqlColumnEncryption -ColumnEncryptionSettings $ces -InputObject $database -LogFileDirectory . -EnclaveAttestationProtocol "AAS" -EnclaveAttestationURL "https://<attestationURL>" -KeyVaultAccessToken $keyVaultAccessToken

Pasos siguientes

Consulte también