Udostępnij za pośrednictwem


Obracanie kluczy Always Encrypted przy użyciu programu PowerShell

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Ten artykuł zawiera kroki rotacji kluczy dla funkcji Always Encrypted przy użyciu modułu SqlServer PowerShell. Aby uzyskać informacje na temat rozpoczynania korzystania z modułu SqlServer PowerShell dla funkcji Always Encrypted, zobacz Configure Always Encrypted using PowerShell.

Rotowanie kluczy Always Encrypted to proces zastępowania istniejącego klucza nowym kluczem. Może być konieczna rotacja klucza, jeśli został naruszony lub w celu przestrzegania zasad lub przepisów dotyczących zgodności organizacji, które wymagają regularnej rotacji kluczy kryptograficznych.

Funkcja Always Encrypted używa dwóch typów kluczy, dlatego istnieją dwa ogólne przepływy pracy rotacji kluczy: rotacja kluczy głównych kolumn i rotacja kluczy szyfrowania kolumn.

  • Rotacja klucza szyfrowania kolumny — polega na odszyfrowywaniu danych zaszyfrowanych bieżącym kluczem i ponownym szyfrowaniu tych danych nowym kluczem szyfrowania kolumny. Ponieważ rotacja klucza szyfrowania kolumny wymaga dostępu zarówno do kluczy, jak i bazy danych, rotacja kluczy szyfrowania kolumny może być wykonywana tylko bez separacji ról.
  • rotacji klucza głównego kolumny — obejmuje odszyfrowywanie kluczy szyfrowania kolumn, które są chronione przy użyciu bieżącego klucza głównego kolumny, ponowne szyfrowanie ich przy użyciu nowego klucza głównego kolumny i aktualizowanie metadanych dla obu typów kluczy. Rotację klucza głównego kolumny można ukończyć z separacją ról lub bez jej (w przypadku korzystania z modułu SqlServer PowerShell).

Rotacja klucza głównego kolumny bez separacji ról

Metoda rotacji klucza głównego kolumny opisanego w tej sekcji nie obsługuje separacji ról między administratorem zabezpieczeń a administratorem bazy danych. Niektóre z poniższych kroków łączą operacje na kluczach fizycznych z operacjami na kluczowych metadanych, dzięki czemu ten przepływ pracy jest zalecany dla organizacji korzystających z modelu DevOps lub gdy baza danych jest hostowana w chmurze, a głównym celem jest ograniczenie administratorów chmury (ale nie lokalnych administratorów baz danych) z uzyskiwania dostępu do poufnych danych. Nie zaleca się, jeśli potencjalni przeciwnicy obejmują administratorów baz danych lub jeśli administratorzy baz danych nie powinni mieć dostępu do poufnych danych.

Zadanie Artykuł Uzyskuje dostęp do kluczy nieszyfrowanych/repozytorium kluczy Uzyskuje dostęp do bazy danych
Krok 1. Utwórz nowy klucz główny dla kolumny w magazynie kluczy.

Uwaga: moduł SqlServer PowerShell nie obsługuje tego kroku. Aby wykonać to zadanie z poziomu wiersza polecenia, należy użyć narzędzi specyficznych dla magazynu kluczy.
Tworzenie i przechowywanie kluczy głównych kolumn dla Always Encrypted Tak Nie
Krok 2. Uruchamianie środowiska programu PowerShell i importowanie modułu SqlServer Importowanie modułu SqlServer Nie Nie
Krok 3. Nawiąż połączenie z serwerem i bazą danych. Nawiązywanie połączenia z bazą danych Nie Tak
Krok 4. Utwórz obiekt SqlColumnMasterKeySettings zawierający informacje o lokalizacji nowego klucza głównego kolumny. SqlColumnMasterKeySettings to obiekt, który istnieje w pamięci (w programie PowerShell). Aby go utworzyć, należy użyć polecenia cmdlet specyficznego dla magazynu kluczy. new-SqlAzureKeyVaultColumnMasterKeySettings

New-SqlCertificateStoreColumnMasterKeySettings

New-SqlCngColumnMasterKeySettings

New-SqlCspColumnMasterKeySettings
Nie Nie
Krok 5. Utwórz metadane dotyczące nowego klucza głównego kolumny w bazie danych. new-SqlColumnMasterKey

Uwaga: w ukryciu, to polecenie cmdlet wystawia CREATE COLUMN MASTER KEY (Transact-SQL) instrukcję w celu utworzenia metadanych klucza.
Nie Tak
Krok 6. Uwierzytelnij się w usłudze Azure, jeśli bieżący klucz główny kolumny lub nowy klucz główny kolumny jest przechowywany w magazynie kluczy lub zarządzanym HSM w usłudze Azure Key Vault Connect-AzAccount Tak Nie
Krok 7. Uzyskaj token dostępu dla usługi Azure Key Vault, jeśli klucz główny kolumny jest przechowywany w usłudze Azure Key Vault. Get-AzAccessToken Nie Nie
Krok 8. Rozpocznij rotację, szyfrując każdy z kluczy szyfrowania kolumny, które są obecnie chronione za pomocą starego klucza głównego kolumny, używając nowego klucza głównego kolumny. Po wykonaniu tego kroku każdy klucz szyfrowania kolumny, który jest dotknięty (powiązany ze starym rotowanym kluczem głównym kolumny), jest szyfrowany zarówno starym, jak i nowym kluczem głównym kolumny, i ma dwie zaszyfrowane wartości w metadanych bazy danych. Invoke-SqlColumnMasterKeyRotation Tak Tak
Krok 9. Koordynuj się z administratorami wszystkich aplikacji, które wysyłają zapytania o zaszyfrowane kolumny w bazie danych (i są chronione przy użyciu starego klucza głównego kolumny), aby zapewnić aplikacjom dostęp do nowego klucza głównego kolumny. Tworzenie i Przechowywanie Kluczy Wzorca Kolumn (Always Encrypted) Tak Nie
Krok 10. Ukończ rotację

Uwaga: przed wykonaniem tego kroku upewnij się, że wszystkie aplikacje, które wysyłają zapytania o zaszyfrowane kolumny chronione za pomocą starego klucza głównego kolumny, zostały skonfigurowane do używania nowego klucza głównego kolumny. W przypadku przedwczesnego wykonania tego kroku niektóre z tych aplikacji mogą nie być w stanie odszyfrować danych. Ukończ rotację, usuwając zaszyfrowane wartości z bazy danych utworzonej przy użyciu starego klucza głównego dla kolumn. Spowoduje to usunięcie skojarzenia między starym kluczem głównym kolumn a kluczami szyfrowania kolumn, które chroni.
Complete-SqlColumnMasterKeyRotation Nie Tak
Krok 10. Usuń metadane ze starego klucza głównego kolumny. Remove-SqlColumnMasterKey Nie Tak

Notatka

Zdecydowanie zaleca się, aby nie usuwać trwale starego klucza głównego kolumny po rotacji. Zamiast tego należy przechowywać stary klucz główny kolumny w aktualnym magazynie kluczy lub zarchiwizować go w innym bezpiecznym miejscu. Jeśli przywracasz bazę danych z pliku kopii zapasowej do punktu w czasie , zanim zostanie skonfigurowany nowy klucz główny kolumny, będziesz potrzebować starego klucza do dostępu do danych.

Obracanie klucza głównego kolumny bez separacji ról (przykład certyfikatu systemu Windows)

Poniższy skrypt jest przykładem kompleksowym, który pokazuje, jak zastąpić istniejący kolumnowy klucz główny (CMK1) nowym kolumnowym kluczem głównym (CMK2).

# Create a new column master key in Windows Certificate Store.
$cert = New-SelfSignedCertificate -Subject "AlwaysEncryptedCert" -CertStoreLocation Cert:CurrentUser\My -KeyExportPolicy Exportable -Type DocumentEncryptionCert -KeyUsage KeyEncipherment -KeySpec KeyExchange -KeyLength 2048

# Import the SqlServer module
Import-Module "SqlServer"

# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Change the authentication method in the connection string, if needed.
$connStr = "Server = " + $serverName + "; Database = " + $databaseName + "; Integrated Security = True; TrustServerCertificate = True"
$database = Get-SqlDatabase -ConnectionString $connStr

# Create a SqlColumnMasterKeySettings object for your new column master key. 
$newCmkSettings = New-SqlCertificateStoreColumnMasterKeySettings -CertificateStoreLocation "CurrentUser" -Thumbprint $cert.Thumbprint

# Create metadata for your new column master key in the database.
$newCmkName = "CMK2"
New-SqlColumnMasterKey -Name $newCmkName -InputObject $database -ColumnMasterKeySettings $newCmkSettings

# Initiate the rotation from the current column master key to the new column master key.
$oldCmkName = "CMK1"
Invoke-SqlColumnMasterKeyRotation -SourceColumnMasterKeyName $oldCmkName -TargetColumnMasterKeyName $newCmkName -InputObject $database

# Complete the rotation of the old column master key.
Complete-SqlColumnMasterKeyRotation -SourceColumnMasterKeyName $oldCmkName  -InputObject $database

# Remove the old column master key metadata.
Remove-SqlColumnMasterKey -Name $oldCmkName -InputObject $database

Rotacja klucza głównego dla kolumny z oddzieleniem ról

Przepływ pracy rotacji klucza głównego kolumny opisany w tej sekcji zapewnia rozdzielenie między administratorem zabezpieczeń a administratorem bazy danych.

Ważny

Przed wykonaniem jakichkolwiek kroków, w których Uzyskuje dostęp do kluczy w postaci zwykłego tekstu/magazynu kluczy=Tak w poniższej tabeli (kroki umożliwiające dostęp do kluczy w postaci zwykłego tekstu lub magazynu kluczy), upewnij się, że środowisko programu PowerShell działa na bezpiecznej maszynie innej niż komputer hostujący bazę danych. Aby uzyskać więcej informacji, zobacz Zagadnienia dotyczące zabezpieczeń dotyczące zarządzania kluczami.

Część 1: DBA

Administrator bazy danych pobiera metadane dotyczące klucza głównego kolumny, który ma zostać obrócony, oraz na temat kluczy szyfrowania kolumny, na które wpływa i które są skojarzone z bieżącym kluczem głównym kolumny. Administrator bazy danych udostępnia wszystkie te informacje administratorowi zabezpieczeń.

Zadanie Artykuł Uzyskuje dostęp do kluczy w postaci zwykłego tekstu/magazynu kluczy Uzyskuje dostęp do bazy danych
Krok 1. Uruchom środowisko programu PowerShell i zaimportuj moduł SqlServer. Importowanie modułu SqlServer Nie Żaden
Krok 2. Nawiąż połączenie z serwerem i bazą danych. Nawiązywanie połączenia z bazą danych Nie Tak
Krok 3. Pobierz metadane dotyczące starego klucza głównego kolumny. Get-SqlColumnMasterKey Nie Tak
Krok 4. Pobierz metadane dotyczące kluczy szyfrowania kolumn chronionych przez stary klucz główny kolumny, w tym ich zaszyfrowane wartości. get-SqlColumnEncryptionKey Nie Tak
Krok 5. Udostępnij lokalizację klucza głównego kolumny (nazwę dostawcy i ścieżkę klucza głównego kolumny) oraz zaszyfrowane wartości odpowiednich kluczy szyfrowania kolumny, zabezpieczone starym kluczem głównym kolumny. Zapoznaj się z poniższymi przykładami. Nie Nie

Część 2. Administrator zabezpieczeń

Administrator zabezpieczeń generuje nowy klucz główny kolumny, ponownie szyfruje dotknięte klucze szyfrowania kolumn przy użyciu nowego klucza głównego kolumny i udostępnia informacje o nowym kluczu głównym kolumny oraz zestaw nowych zaszyfrowanych wartości dla dotkniętych kluczy szyfrowania kolumn administratorowi baz danych.

Zadanie Artykuł Uzyskiwanie dostępu do kluczy w postaci zwykłego tekstu/magazynu kluczy Uzyskuje dostęp do bazy danych
Krok 1. Uzyskaj lokalizację starego klucza głównego kolumny oraz zaszyfrowane wartości odpowiadających kluczy szyfrowania kolumny, chronione przy użyciu starego klucza głównego kolumny, od swojego administratora bazy danych (DBA). N/A
Zapoznaj się z poniższymi przykładami.
Nie Nie
Krok 2. Utwórz nowy klucz nadrzędny kolumny w magazynie kluczy.

Uwaga: moduł SqlServer nie obsługuje tego kroku. Aby wykonać to zadanie z poziomu wiersza polecenia, należy użyć narzędzi specyficznych dla typu magazynu kluczy.
Tworzenie i przechowywanie głównych kluczy kolumn dla Always Encrypted Tak Nie
Krok 3. Uruchom środowisko programu PowerShell i zaimportuj moduł SqlServer. Importowanie modułu SqlServer Nie Nie
Krok 4. Utwórz obiekt SqlColumnMasterKeySettings zawierający informacje o lokalizacji starego klucza głównego kolumny . SqlColumnMasterKeySettings to obiekt, który istnieje w pamięci (w programie PowerShell). New-SqlColumnMasterKeySettings Nie Nie
Krok 5. Utwórz obiekt SqlColumnMasterKeySettings, który zawiera informacje o lokalizacji nowego klucza kolumny głównej . SqlColumnMasterKeySettings to obiekt, który istnieje w pamięci (w programie PowerShell). Aby go utworzyć, należy użyć polecenia cmdlet specyficznego dla magazynu kluczy. new-SqlAzureKeyVaultColumnMasterKeySettings

New-SqlCertificateStoreColumnMasterKeySettings

New-SqlCngColumnMasterKeySettings

New-SqlCspColumnMasterKeySettings
Nie Nie
Krok 6. Uwierzytelnij się na platformie Azure, jeśli stary (bieżący) klucz główny kolumny lub nowy klucz główny kolumny jest przechowywany w magazynie kluczy lub zarządzanym module HSM w usłudze Azure Key Vault. Connect-AzAccount Tak Nie
Krok 7. Uzyskaj token dostępu dla Azure Key Vault, jeśli kolumnowy klucz główny jest przechowywany w Azure Key Vault. Get-AzAccessToken Nie Nie
Krok 8. Zaszyfruj ponownie każdą wartość klucza szyfrowania kolumny, która jest obecnie chroniona przy użyciu starego klucza głównego kolumny przy użyciu nowego klucza głównego kolumny. new-SqlColumnEncryptionKeyEncryptedValue

Uwaga: Podczas wywoływania tego polecenia cmdlet przekaż obiekty SqlColumnMasterKeySettings zarówno dla starego, jak i nowego klucza głównego kolumny wraz z wartością klucza szyfrowania kolumny, które mają zostać ponownie zaszyfrowane.
Tak Nie
Krok 9. Udostępnij lokalizację nowego klucza głównego kolumny (nazwę dostawcy i ścieżkę klucza głównego kolumny) oraz zestaw nowych zaszyfrowanych wartości kluczy szyfrowania kolumny, twojemu administratorowi baz danych. Zapoznaj się z poniższymi przykładami. Nie Nie

Notatka

Zdecydowanie zaleca się, aby nie usuwać trwale starego głównego klucza kolumny po przeprowadzeniu rotacji. Zamiast tego należy pozostawić stary klucz główny kolumn w bieżącym magazynie kluczy lub zarchiwizować go w innym bezpiecznym miejscu. Jeśli przywrócisz bazę danych z pliku kopii zapasowej do punktu w czasie , zanim skonfigurowano nowy klucz główny kolumny, będziesz potrzebował starego klucza, aby uzyskać dostęp do danych.

Część 3: DBA

Administrator bazy danych tworzy metadane dla nowego klucza głównego kolumny i aktualizuje metadane kluczy szyfrowania kolumn, których to dotyczy, aby dodać nowy zestaw zaszyfrowanych wartości. W tym kroku administrator bazy danych koordynuje również z administratorami aplikacji wykonujących zapytania dotyczące kolumn szyfrowania, którzy zapewniają aplikacji dostęp do nowego klucza głównego kolumny. Po skonfigurowaniu wszystkich aplikacji do używania nowego klucza głównego kolumny administrator bazy danych usuwa stary zestaw zaszyfrowanych wartości i stare metadane klucza głównego kolumny.

Zadanie Artykuł Uzyskiwanie dostępu do kluczy w postaci zwykłego tekstu/magazynu kluczy Uzyskuje dostęp do bazy danych
Krok 1. Uzyskaj lokalizację nowego klucza głównego kolumny i nowy zestaw zaszyfrowanych wartości odpowiednich kluczy szyfrowania kolumny, chroniony za pomocą starego klucza głównego kolumny od administratora zabezpieczeń. Zapoznaj się z poniższymi przykładami. Nie Nie
Krok 2. Uruchom środowisko programu PowerShell i zaimportuj moduł SqlServer. Importowanie modułu SqlServer Nie Nie
Krok 3. Nawiąż połączenie z serwerem i bazą danych. Nawiązywanie połączenia z bazą danych Nie Tak
Krok 4. Utwórz obiekt SqlColumnMasterKeySettings zawierający informacje o lokalizacji nowego klucza głównego kolumny. SqlColumnMasterKeySettings to obiekt, który istnieje w pamięci (w programie PowerShell). New-SqlColumnMasterKeySettings Nie Nie
Krok 5. Utwórz metadane dotyczące nowego klucza głównego kolumny w bazie danych. new-SqlColumnMasterKey

Uwaga: W ramach tego polecenia cmdlet CREATE COLUMN MASTER KEY (Transact-SQL) instrukcja w celu utworzenia metadanych klucza.
Nie Tak
Krok 6. Pobierz metadane dotyczące kluczy szyfrowania kolumn chronionych przez stary klucz główny kolumny. get-SqlColumnEncryptionKey Nie Tak
Krok 7. Dodaj nową zaszyfrowaną wartość (utworzoną przy użyciu nowego klucza głównego kolumny) do metadanych dla każdego klucza szyfrowania kolumny, której dotyczy ten wpływ. add-SqlColumnEncryptionKeyValue Nie Tak
Krok 8. Koordynuj się z administratorami wszystkich aplikacji, które wysyłają zapytania o zaszyfrowane kolumny w bazie danych (i są chronione przy użyciu starego klucza głównego kolumny), aby zapewnić aplikacjom dostęp do nowego klucza głównego kolumny. Tworzenie i przechowywanie kluczy głównych kolumn (Always Encrypted) Nie Nie
Krok 9. Ukończ rotację, usuwając zaszyfrowane wartości skojarzone ze starym kluczem głównym kolumny z bazy danych.

Uwaga: Przed wykonaniem tego kroku upewnij się, że wszystkie aplikacje, które wysyłają zapytania o zaszyfrowane kolumny chronione przy użyciu starego klucza głównego kolumny, zostały skonfigurowane do używania nowego klucza głównego kolumny. W przypadku przedwczesnego wykonania tego kroku niektóre z tych aplikacji mogą nie być w stanie odszyfrować danych.

Ten krok usuwa skojarzenie między starym kluczem głównym kolumny a kluczami szyfrowania kolumn, które chroni.
Complete-SqlColumnMasterKeyRotation

Alternatywnie możesz użyć Remove-SqlColumnEncryptionKeyValue
Nie Tak
Krok 10. Usuwanie starych metadanych klucza głównego kolumny z bazy danych Remove-SqlColumnMasterKey Nie Tak

Rotacja klucza głównego kolumny z podziałem ról (na przykładzie certyfikatu systemu Windows)

Poniższy skrypt to kompleksowy przykład generowania nowego klucza głównego kolumny, który jest certyfikatem w magazynie certyfikatów systemu Windows, rotowanie istniejącego (bieżącego) klucza głównego kolumny, aby zastąpić go nowym kluczem głównym kolumny. Skrypt zakłada, że docelowa baza danych zawiera klucz główny kolumny o nazwie CMK1, który ma zostać zrotowany i który szyfruje niektóre klucze szyfrowania kolumny.

Część 1: DBA

# Import the SqlServer module.
Import-Module "SqlServer"

# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Change the authentication method in the connection string, if needed.
$connStr = "Server = " + $serverName + "; Database = " + $databaseName + "; Integrated Security = True; TrustServerCertificate = True"
$database = Get-SqlDatabase -ConnectionString $connStr

# Retrieve the data about the old column master key, which needs to be rotated.
$oldCmkName = "CMK1"
$oldCmk = Get-SqlColumnMasterKey -Name $oldCmkName -InputObject $database


# Share the location of the old column master key with a Security Administrator, via a CSV file on a share drive.
$oldCmkDataFile = "Z:\oldcmkdata.txt"
"KeyStoreProviderName, KeyPath" > $oldCmkDataFile
$oldCmk.KeyStoreProviderName +", " + $oldCmk.KeyPath >> $oldCmkDataFile


# Find column encryption keys associated with the old column master key and provide the encrypted values of column encryption keys to the Security Administrator, via a CSV file on a share drive.
$ceks = Get-SqlColumnEncryptionKey -InputObject $database
$oldCekValuesFile = "Z:\oldcekvalues.txt"
"CEKName, CEKEncryptedValue" > $oldCekValuesFile 
for($i=0; $i -lt $ceks.Length; $i++){
    if($ceks[$i].ColumnEncryptionKeyValues.Length -eq 2) {
        # This column encryption has 2 encrypted values - let's check, if it is associated with the old column master key.
        if($ceks[$i].ColumnEncryptionKeyValues[0].ColumnMasterKeyName -eq $oldCmkName -or $ceks[$i].ColumnEncryptionKeyValues[1].ColumnMasterKeyName -eq $oldCmkName) {
            Write-Host $ceks[$i].Name "already has 2 encrypted values and therefore" $oldCmkName + "cannot be rotated"
            exit 1
        }
    }
    if($ceks[$i].ColumnEncryptionKeyValues[0].ColumnMasterKeyName -eq $oldCmkName) {# This column encryption key has 1 encrypted value that was produced using the old column master key
        # Save the name and the encrypted value of the column encryption key in the file.
        $encryptedValue =  "0x" + -join ($ceks[$i].ColumnEncryptionKeyValues[0].EncryptedValue |  foreach {$_.ToString("X2") } )
        $ceks[$i].Name + "," + $encryptedValue >> $oldCekValuesFile
    }
} 

Część 2. Administrator zabezpieczeń

# Obtain the location of the old column master key and the encrypted values of the corresponding column encryption keys, from your DBA, via a CSV file on a share drive.
$oldCmkDataFile = "Z:\oldcmkdata.txt"
$oldCmkData = Import-Csv $oldCmkDataFile
$oldCekValuesFile = "Z:\oldcekvalues.txt"
$oldCekValues = @(Import-Csv $oldCekValuesFile)

# Create a new column master key in Windows Certificate Store.
$storeLocation = "CurrentUser"
$certPath = "Cert:\" + $storeLocation + "\My"
$cert = New-SelfSignedCertificate -Subject "AlwaysEncryptedCert" -CertStoreLocation $certPath -KeyExportPolicy Exportable -Type DocumentEncryptionCert -KeyUsage DataEncipherment -KeySpec KeyExchange

# Import the SqlServer module.
Import-Module "SqlServer"

# Create a SqlColumnMasterKeySettings object for your old column master key. 
$oldCmkSettings = New-SqlColumnMasterKeySettings -KeyStoreProviderName $oldCmkData.KeyStoreProviderName -KeyPath $oldCmkData.KeyPath

# Create a SqlColumnMasterKeySettings object for your new column master key. 
$newCmkSettings = New-SqlCertificateStoreColumnMasterKeySettings -CertificateStoreLocation $storeLocation -Thumbprint $cert.Thumbprint


# Prepare a CSV file, you will use to share the encrypted values of column encryption keys, produced using the new column master key.
$newCekValuesFile = "Z:\newcekvalues.txt"
"CEKName, CEKEncryptedValue" > $newCekValuesFile

# Re-encrypt each value with the new column master key and save the new encrypted value in the file.
for($i=0; $i -lt $oldCekValues.Count; $i++){
    # Re-encrypt each value with the new CMK
    $newValue = New-SqlColumnEncryptionKeyEncryptedValue -TargetColumnMasterKeySettings $newCmkSettings -ColumnMasterKeySettings $oldCmkSettings -EncryptedValue $oldCekValues[$i].CEKEncryptedValue
    $oldCekValues[$i].CEKName + ", " + $newValue >> $newCekValuesFile
}

# Share the new column master key data with your DBA, via a CSV file.
$newCmkDataFile = $home + "\newcmkdata.txt"
"KeyStoreProviderName, KeyPath" > $newCmkDataFile
$newCmkSettings.KeyStoreProviderName +", " + $newCmkSettings.KeyPath >> $newCmkDataFile

Część 3: DBA

# Obtain the location of the new column master key and the new encrypted values of the corresponding column encryption keys, from your Security Administrator, via a CSV file on a share drive.
$newCmkDataFile = "Z:\newcmkdata.txt"
$newCmkData = Import-Csv $newCmkDataFile
$newCekValuesFile = "Z:\newcekvalues.txt"
$newCekValues = @(Import-Csv $newCekValuesFile)

# Import the SqlServer module.
Import-Module "SqlServer"

# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Change the authentication method in the connection string, if needed.
$connStr = "Server = " + $serverName + "; Database = " + $databaseName + "; Integrated Security = True; TrustServerCertificate = True"
$database = Get-SqlDatabase -ConnectionString $connStr

# Create a SqlColumnMasterKeySettings object for your new column master key. 
$newCmkSettings = New-SqlColumnMasterKeySettings -KeyStoreProviderName $newCmkData.KeyStoreProviderName -KeyPath $newCmkData.KeyPath
# Create metadata for the new column master key in the database.
$newCmkName = "CMK2"
New-SqlColumnMasterKey -Name $newCmkName -InputObject $database -ColumnMasterKeySettings $newCmkSettings


# Get all CEK objects
$oldCmkName = "CMK1"
$ceks = Get-SqlColumnEncryptionKey -InputObject $database
for($i=0; $i -lt $ceks.Length; $i++){
    if($ceks[$i].ColumnEncryptionKeyValues.Length -eq 2) {# This column encryption key has 2 encrypted values. Let's check, if it is associated with the old CMK.
        if($ceks[$i].ColumnEncryptionKeyValues[0].ColumnMasterKeyName -eq $oldCmkName -or $ceks[$i].ColumnEncryptionKeyValues[1].ColumnMasterKeyName -eq $oldCmkName) {
            Write-Host $ceks[$i].Name "already has 2 encrypted values and therefore" $oldCmkName + "cannot be rotated"
            exit 1
        }
    }
    if($ceks[$i].ColumnEncryptionKeyValues[0].ColumnMasterKeyName -eq $oldCmkName) {
        # Find the corresponding new encrypted value, received from the Security Administrator.
        $newValueRow = ($newCekValues| Where-Object {$_.CEKName -eq $ceks[$i].Name }[0])
        # Update the column encryption key metadata object by adding the new encrypted value
        Add-SqlColumnEncryptionKeyValue -ColumnMasterKeyName $newCmkName -Name $ceks[$i].Name -EncryptedValue $newValueRow.CEKEncryptedValue -InputObject $database 
    }
}

# Complete the rotation of the current column master key.
Complete-SqlColumnMasterKeyRotation -SourceColumnMasterKeyName $oldCmkName  -InputObject $database

# Remove the old column master key.
Remove-SqlColumnMasterKey -Name $oldCmkName -InputObject $database

Obracanie klucza szyfrowania kolumny

Rotacja klucza szyfrowania kolumny obejmuje odszyfrowanie danych we wszystkich kolumnach, które były zaszyfrowane przy użyciu klucza, który ma być rotowany, i ponowne zaszyfrowanie danych przy użyciu nowego klucza szyfrowania kolumny. Ten proces rotacji wymaga dostępu zarówno do kluczy, jak i bazy danych, dlatego nie można go przeprowadzić z podziałem ról. Rotacja klucza szyfrowania kolumny może zająć dużo czasu, jeśli duże tabele zawierają kolumny zaszyfrowane z użyciem klucza, który jest aktualnie rotowany. W związku z tym organizacja musi dokładnie zaplanować rotację kluczy szyfrowania kolumn.

Klucz szyfrowania kolumny można obrócić, stosując metodę offline lub online. Poprzednia metoda prawdopodobnie będzie szybsza, ale aplikacje nie mogą zapisywać w zablokowanych tabelach. To drugie podejście prawdopodobnie potrwa dłużej, ale można ograniczyć interwał czasu, w którym tabele, których dotyczy problem, nie są dostępne dla aplikacji. Aby uzyskać więcej informacji, zobacz Konfiguracja szyfrowania kolumn przy użyciu Always Encrypted z PowerShell oraz Set-SqlColumnEncryption.

Zadanie Artykuł Uzyskuje dostęp do kluczy w postaci zwykłego tekstu lub do magazynu kluczy Uzyskuje dostęp do bazy danych
Krok 1. Uruchom środowisko programu PowerShell i zaimportuj moduł SqlServer. Importowanie modułu SqlServer Nie Nie
Krok 2. Nawiąż połączenie z serwerem i bazą danych. Nawiązywanie połączenia z bazą danych Nie Tak
Krok 3. Uwierzytelnij się w Azure, jeśli klucz główny kolumny, chroniący klucz szyfrowania kolumny, który ma być rotowany, jest przechowywany w Azure Key Vault lub zarządzanym module HSM. Connect-AzAccount Tak Nie
Krok 4. Uzyskaj token dostępu dla usługi Azure Key Vault, jeśli klucz główny kolumny jest przechowywany w usłudze Azure Key Vault. Get-AzAccessToken Nie Nie
Krok 5. Wygeneruj nowy klucz szyfrowania kolumny, zaszyfruj go przy użyciu klucza głównego kolumny i utwórz metadane klucza szyfrowania kolumny w bazie danych. new-SqlColumnEncryptionKey

Uwaga: Użyj odmiany polecenia cmdlet, które wewnętrznie generuje i szyfruje klucz szyfrowania kolumny.
W ramach działania tego polecenia cmdlet wykonywana jest instrukcja CREATE COLUMN ENCRYPTION KEY (Transact-SQL) w celu utworzenia metadanych klucza.
Tak Tak
Krok 6. Znajdź wszystkie kolumny zaszyfrowane przy użyciu starego klucza szyfrowania kolumny. Przewodnik programowania obiektów zarządzania programem SQL Server (SMO) Nie Tak
Krok 7. Utwórz obiekt SqlColumnEncryptionSettings dla każdej kolumny, której to dotyczy. SqlColumnEncryptionSettings to obiekt, który istnieje w pamięci (w programie PowerShell). Określa docelowy schemat szyfrowania dla kolumny. W takim przypadku obiekt powinien określać, że dotknięta kolumna powinna być szyfrowana przy użyciu nowego klucza szyfrowania. New-SqlColumnEncryptionSettings Nie Nie
Krok 8. Ponownie zaszyfruj kolumny zidentyfikowane w kroku 5 przy użyciu nowego klucza szyfrowania kolumny. Set-SqlColumnEncryption

Uwaga: ten krok może zająć dużo czasu. Aplikacje nie będą mogły uzyskiwać dostępu do tabel za pośrednictwem całej operacji lub jej części, w zależności od wybranego podejścia (online a offline).
Tak Tak
Krok 9. Usuń metadane starego klucza szyfrowania kolumny. Remove-SqlColumnEncryptionKey Nie Tak

Przykład — obracanie klucza szyfrowania kolumny

Poniższy skrypt demonstruje rotację klucza szyfrowania kolumny. Skrypt zakłada, że docelowa baza danych zawiera kilka kolumn zaszyfrowanych kluczem szyfrowania kolumny o nazwie CEK1, który ma być rotowany i jest chroniony za pomocą klucza głównego kolumny o nazwie CMK1 (klucz główny kolumny nie jest przechowywany w usłudze Azure Key Vault).

# Import the SqlServer module.
Import-Module "SqlServer"

# Connect to your database.
$serverName = "<server name>"
$databaseName = "<database name>"
# Change the authentication method in the connection string, if needed.
$connStr = "Server = " + $serverName + "; Database = " + $databaseName + "; Integrated Security = True; TrustServerCertificate = True"
$database = Get-SqlDatabase -ConnectionString $connStr

# Generate a new column encryption key, encrypt it with the column master key and create column encryption key metadata in the database. 
$cmkName = "CMK1"
$newCekName = "CEK2"
New-SqlColumnEncryptionKey -Name $newCekName -InputObject $database -ColumnMasterKey $cmkName 


# Find all columns encrypted with the old column encryption key, and create a SqlColumnEncryptionSetting object for each column.
$ces = @()
$oldCekName = "CEK1"
$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 -and $columns[$j].ColumnEncryptionKeyName -eq $oldCekName) {
            $threeColPartName = $tables[$i].Schema + "." + $tables[$i].Name + "." + $columns[$j].Name 
            $ces += New-SqlColumnEncryptionSettings -ColumnName $threeColPartName -EncryptionType $columns[$j].EncryptionType -EncryptionKey $newCekName
        }
     }
}

# Re-encrypt all columns, currently encrypted with the old column encryption key, using the new column encryption key.
Set-SqlColumnEncryption -ColumnEncryptionSettings $ces -InputObject $database -UseOnlineApproach -MaxDowntimeInSeconds 120 -LogFileDirectory .

# Remove the old column encryption key metadata.
Remove-SqlColumnEncryptionKey -Name $oldCekName -InputObject $database

Następne kroki

Zobacz też