PowerShell을 사용하여 Always Encrypted 키 순환

적용 대상:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

이 문서에서는 SqlServer PowerShell 모듈을 사용하여 Always Encrypted에 대한 키를 회전하는 단계를 제공합니다. Always Encrypted용 SqlServer PowerShell 모듈 사용을 시작하는 방법에 대한 자세한 내용은 PowerShell을 사용하여 Always Encrypted 구성을 참조하세요.

Always Encrypted 키를 회전하는 프로세스는 기존 키를 새 키로 바꾸는 프로세스입니다. 키가 손상된 경우 또는 암호화 키를 정기적으로 회전해야 하는 조직의 정책 또는 규정 준수 규정을 준수하기 위해 키를 회전해야 할 수 있습니다.

상시 암호화는 두 가지 유형의 키를 사용하므로 열 마스터 키 순환과 열 암호화 키 순환이라는 두 개의 상위 수준 키 순환 워크플로가 있습니다.

  • 열 암호화 키 회전 - 현재 키로 암호화된 데이터의 암호를 해독하고 새 열 암호화 키를 사용하여 데이터를 다시 암호화하는 작업이 포함됩니다. 열 암호화 키를 회전하려면 키와 데이터베이스 모두에 대한 액세스 권한이 필요하므로 열 암호화 키 회전은 역할 분리 없이만 수행할 수 있습니다.
  • 열 마스터 키 회전 - 현재 열 마스터 키로 보호되는 열 암호화 키의 암호를 해독하고, 새 열 마스터 키를 사용하여 다시 암호화하고, 두 유형의 키에 대한 메타데이터를 업데이트하는 작업이 포함됩니다. 열 마스터 키 순환은 역할 구분에 관계없이 완료할 수 있습니다(SqlServer PowerShell 모듈 사용 시).

역할 구분을 사용하지 않는 열 마스터 키 순환

이 섹션에서 설명하는 열 마스터 키를 회전하는 방법은 보안 관리자와 DBA 간의 역할 분리를 지원하지 않습니다. 아래 단계 중 일부는 물리적 키에 대한 작업을 키 메타데이터에 대한 작업과 결합하므로 이 워크플로는 DevOps 모델을 사용하는 조직에 권장되거나 데이터베이스가 클라우드에서 호스트되고 주요 목표는 클라우드 관리자(온-프레미스 DBA가 아님)가 중요한 데이터에 액세스하지 못하도록 제한하는 것입니다. 잠재적인 악의적 사용자가 DBA를 포함하거나 DBA가 중요한 데이터에 액세스할 수 없는 경우에는 권장되지 않습니다.

Task 아티클 일반 텍스트 키/키 저장소에 액세스 데이터베이스에 액세스
1단계 키 저장소에 새 열 마스터 키를 만듭니다.

참고: SqlServer PowerShell 모듈은 이 단계를 지원하지 않습니다. 명령줄에서 이 작업을 수행하려면 키 저장소에 특정한 도구를 사용해야 합니다.
Always Encrypted에 대한 열 마스터 키 만들기 및 저장 없음
2단계. PowerShell 환경을 시작하고 SqlServer 모듈 가져오기 SqlServer 모듈 가져오기 없음 없음
3단계: 서버 및 데이터베이스에 연결합니다. 데이터베이스에 연결 없음
4단계. 새 열 마스터 키의 위치에 대한 정보가 포함된 SqlColumnMasterKeySettings 개체를 만듭니다. SqlColumnMasterKeySettings는 PowerShell의 메모리에 있는 개체입니다. 만들려면 키 저장소와 관련된 cmdlet을 사용해야 합니다. New-SqlAzureKeyVaultColumnMasterKeySettings

New-SqlCertificateStoreColumnMasterKeySettings

New-SqlCngColumnMasterKeySettings

New-SqlCspColumnMasterKeySettings
없음 없음
5단계. 데이터베이스에서 새 열 마스터 키에 대한 메타데이터를 만듭니다. New-SqlColumnMasterKey

참고: 이 cmdlet은 아래에 CREATE COLUMN MASTER KEY(Transact-SQL) 문을 실행하여 키 메타데이터를 만듭니다.
없음
6단계 현재 열 마스터 키 또는 새 열 마스터 키가 키 자격 증명 모음 또는 Azure Key Vault의 관리형 HSM에 저장된 경우 Azure에 인증 Connect-AzAccount 없음
7단계 열 마스터 키가 Azure Key Vault에 저장된 경우 Azure Key Vault에 대한 액세스 토큰을 가져옵니다. Get-AzAccessToken 없음 없음
8단계: 이전 열 마스터 키로 현재 보호된 열 암호화 키를 각각 새 열 마스터 키로 암호화하여 순환을 시작합니다. 이 단계 후에 영향을 받은 각 열 암호화 키(이전 열 마스터 키와 연결됨, 순환됨)는 이전 및 새 열 마스터 키로 암호화되고 데이터베이스 메타데이터에 두 개의 암호화된 값이 있습니다. Invoke-SqlColumnMasterKeyRotation
9단계. 데이터베이스의 암호화된 열을 쿼리하며 이전 열 마스터 키로 보호된 모든 애플리케이션의 관리자와 협력하여 애플리케이션이 새 열 마스터 키에 액세스할 수 있도록 합니다. 열 마스터 키 만들기 및 저장(Always Encrypted) 없음
10단계. 순환을 완료합니다.

참고: 이 단계를 실행하기 전에 이전 열 마스터 키로 보호되는 암호화된 열을 쿼리하는 모든 애플리케이션이 새 열 마스터 키를 사용하도록 구성되었는지 확인합니다. 이 단계를 조기에 수행하는 경우 일부 애플리케이션에서 데이터 암호를 해독하지 못할 수 있습니다. 이전 열 마스터 키로 만든 데이터베이스에서 암호화된 값을 제거하여 회전을 완료합니다. 이렇게 하면 이전 열 마스터 키와 보호되는 열 암호화 키 간의 연결이 제거됩니다.
Complete-SqlColumnMasterKeyRotation 없음
10단계. 이전 열 마스터 키에서 메타데이터를 제거합니다. Remove-SqlColumnMasterKey 없음

참고 항목

회전 후 이전 열 마스터 키를 영구적으로 삭제하지 않는 것이 좋습니다. 대신 이전 열 마스터 키를 현재 키 저장소에 유지하거나 다른 안전한 위치에 보관해야 합니다. 백업 파일에서 새 열 마스터 키가 구성되기 전의 시점으로 데이터베이스를 복원하는 경우 데이터에 액세스하려면 이전 키가 필요합니다.

역할 구분 없이 열 마스터 키 회전(Windows 인증서 예제)

아래 스크립트는 기존 CMK1(열 마스터 키)을 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"
$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

역할 분리를 사용하여 열 마스터 키 회전

이 섹션에 설명된 열 마스터 키 회전 워크플로는 보안 관리자와 DBA 간의 분리를 보장합니다.

Important

아래 표에서 일반 텍스트 키/키 저장소=예에 액세스하는 단계(일반 텍스트 키 또는 키 저장소에 액세스하는 단계)를 실행하기 전에 PowerShell 환경이 데이터베이스를 호스팅하는 컴퓨터와 다른 보안 컴퓨터에서 실행되는지 확인합니다. 자세한 내용은 키 관리에 대한 보안 고려 사항을 참조하세요.

1부: DBA

DBA가 순환할 열 마스터 키 및 현재 열 마스터 키와 연결된 영향을 받는 열 암호화 키에 대한 메타데이터를 검색합니다. DBA는 이 모든 정보를 보안 관리자와 공유합니다.

Task 아티클 일반 텍스트 키/키 저장소에 액세스 데이터베이스에 액세스
1단계 PowerShell 환경을 시작하고 SqlServer 모듈을 가져옵니다. SqlServer 모듈 가져오기 없음 아니요
2단계. 서버 및 데이터베이스에 연결합니다. 데이터베이스에 연결 없음
3단계: 이전 열 마스터 키에 대한 메타데이터를 검색합니다. Get-SqlColumnMasterKey 없음
4단계. 암호화된 값을 포함하여 이전 열 마스터 키로 보호된 열 암호화 키에 대한 메타데이터를 검색합니다. Get-SqlColumnEncryptionKey 없음
5단계. 열 마스터 키의 위치(공급자 이름 및 열 마스터 키의 키 경로) 및 이전 열 마스터 키로 보호되는 해당 열 암호화 키의 암호화된 값을 공유합니다. 아래 예제를 참조하세요. 없음 없음

2부: 보안 관리자

보안 관리자는 새 열 마스터 키를 생성하고, 영향을 받은 열 암호화 키를 새 열 마스터 키로 다시 암호화하고, 새 열 마스터 키에 대한 정보와 영향을 받은 열 암호화 키에 대한 새 암호화된 값 집합을 DBA와 공유합니다.

Task 아티클 일반 텍스트 키/키 저장소에 액세스 데이터베이스에 액세스
1단계 이전 열 마스터 키의 위치와 이전 열 마스터 키로 보호된 해당 열 암호화 키의 암호화된 값을 DBA로부터 얻습니다. 해당 없음
아래 예제를 참조하세요.
없음 없음
2단계. 키 저장소에 새 열 마스터 키를 만듭니다.

참고: SqlServer 모듈은 이 단계를 지원하지 않습니다. 명령줄에서 이 작업을 수행하려면 키 저장소의 유형과 관련된 도구를 사용해야 합니다.
Always Encrypted에 대한 열 마스터 키 만들기 및 저장 없음
3단계: PowerShell 환경을 시작하고 SqlServer 모듈을 가져옵니다. SqlServer 모듈 가져오기 없음 없음
4단계. 이전 열 마스터 키의 위치에 대한 정보가 포함된 SqlColumnMasterKeySettings 개체를 만듭니다. SqlColumnMasterKeySettings는 PowerShell의 메모리에 있는 개체입니다. New-SqlColumnMasterKeySettings 없음 없음
5단계. 새 열 마스터 키의 위치에 대한 정보가 포함된 SqlColumnMasterKeySettings 개체를 만듭니다. SqlColumnMasterKeySettings는 PowerShell의 메모리에 있는 개체입니다. 만들려면 키 저장소와 관련된 cmdlet을 사용해야 합니다. New-SqlAzureKeyVaultColumnMasterKeySettings

New-SqlCertificateStoreColumnMasterKeySettings

New-SqlCngColumnMasterKeySettings

New-SqlCspColumnMasterKeySettings
없음 없음
6단계 이전(현재) 열 마스터 키 또는 새 열 마스터 키가 Azure Key Vault의 관리형 HSM 또는 키 자격 증명 모음에 저장된 경우 Azure에 인증합니다. Connect-AzAccount 없음
7단계 열 마스터 키가 Azure Key Vault에 저장된 경우 Azure Key Vault에 대한 액세스 토큰을 가져옵니다. Get-AzAccessToken 없음 없음
8단계: 이전 열 마스터 키로 현재 보호된 열 암호화 키의 값을 각각 새 열 마스터 키로 다시 암호화합니다. New-SqlColumnEncryptionKeyEncryptedValue

참고: 이 cmdlet을 호출할 때 다시 암호화할 열 암호화 키의 값과 함께 이전 열 마스터 키와 새 열 마스터 키 둘 다의 SqlColumnMasterKeySettings 개체를 전달합니다.
없음
9단계. 새 열 마스터 키의 위치(공급자 이름 및 열 마스터 키의 키 경로) 및 열 암호화 키의 암호화된 새 값 집합을 DBA와 공유합니다. 아래 예제를 참조하세요. 없음

참고 항목

회전 후 이전 열 마스터 키를 영구적으로 삭제하지 않는 것이 좋습니다. 대신 이전 열 마스터 키를 현재 키 저장소에 유지하거나 다른 안전한 위치에 보관해야 합니다. 백업 파일에서 새 열 마스터 키가 구성되기 전의 시점으로 데이터베이스를 복원하는 경우 데이터에 액세스하려면 이전 키가 필요합니다.

3부: DBA

DBA가 새 열 마스터 키에 대한 메타데이터를 만들고 영향을 받는 열 암호화 키를 업데이트하여 새로 암호화된 값 집합을 추가합니다. 이 단계에서 DBA는 애플리케이션이 새 열 마스터 키에 액세스할 수 있도록 암호화 열을 쿼리하는 애플리케이션의 관리자와도 조정합니다. 모든 애플리케이션이 새 열 마스터 키를 사용하도록 설정되면 DBA가 이전 암호화된 값 집합과 이전 열 마스터 키 메타데이터를 제거합니다.

Task 아티클 일반 텍스트 키/키 저장소에 액세스 데이터베이스에 액세스
1단계 보안 관리자로부터 새 열 마스터 키의 위치와 이전 열 마스터 키로 보호되는 해당 열 암호화 키의 암호화된 값의 새 집합을 가져옵니다. 아래 예제를 참조하세요. 없음 없음
2단계. PowerShell 환경을 시작하고 SqlServer 모듈을 가져옵니다. SqlServer 모듈 가져오기 없음 없음
3단계: 서버 및 데이터베이스에 연결합니다. 데이터베이스에 연결 없음
4단계. 새 열 마스터 키의 위치에 대한 정보가 포함된 SqlColumnMasterKeySettings 개체를 만듭니다. SqlColumnMasterKeySettings는 PowerShell의 메모리에 있는 개체입니다. New-SqlColumnMasterKeySettings 없음 없음
5단계. 데이터베이스에서 새 열 마스터 키에 대한 메타데이터를 만듭니다. New-SqlColumnMasterKey

참고: 이 cmdlet은 아래에 CREATE COLUMN MASTER KEY(Transact-SQL) 문을 실행하여 키 메타데이터를 만듭니다.
없음
6단계 이전 열 마스터 키로 보호되는 열 암호화 키에 대한 메타데이터를 검색합니다. Get-SqlColumnEncryptionKey 없음
7단계 영향을 받은 각 열 암호화 키에 대한 메타데이터에 새 암호화된 값(새 열 마스터 키를 사용하여 생성됨)을 추가합니다. Add-SqlColumnEncryptionKeyValue 없음
8단계: 데이터베이스의 암호화된 열을 쿼리하며 이전 열 마스터 키로 보호된 모든 애플리케이션의 관리자와 협력하여 애플리케이션이 새 열 마스터 키에 액세스할 수 있도록 합니다. 열 마스터 키 만들기 및 저장(Always Encrypted) 없음 없음
9단계. 데이터베이스에서 이전 열 마스터 키와 연결된 암호화된 값을 제거하여 회전을 완료합니다.

참고: 이 단계를 실행하기 전에 이전 열 마스터 키로 보호되는 암호화된 열을 쿼리하는 모든 애플리케이션이 새 열 마스터 키를 사용하도록 구성되었는지 확인합니다. 이 단계를 조기에 수행하는 경우 일부 애플리케이션에서 데이터 암호를 해독하지 못할 수 있습니다.

이 단계에서는 이전 열 마스터 키와 보호되는 열 암호화 키 간의 연결을 제거합니다.
Complete-SqlColumnMasterKeyRotation

또는 Remove-SqlColumnEncryptionKeyValue를 사용할 수 있습니다.
없음
10단계. 데이터베이스에서 이전 열 마스터 키 메타데이터 제거 Remove-SqlColumnMasterKey 없음

역할 구분을 사용하여 열 마스터 키 회전(Windows 인증서 예제)

아래 스크립트는 Windows 인증서 저장소에서 인증서인 새 열 마스터 키를 생성하고 기존(현재) 열 마스터 키를 회전하여 새 열 마스터 키로 바꾸기 위한 엔드 투 엔드 예제입니다. 스크립트는 대상 데이터베이스에 일부 열 암호화 키를 암호화하는 CMK1(회전할)이라는 열 마스터 키가 포함되어 있다고 가정합니다.

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"
$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
    }
} 

2부: 보안 관리자

# 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

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"
$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

열 암호화 키 순환

열 암호화 키를 순환하려면 모든 열에서 순환할 키로 암호화된 데이터의 암호를 해독하고 새 열 암호화 키를 사용하여 데이터를 다시 암호화해야 합니다. 이 순환 워크플로는 키와 데이터베이스에 모두 액세스해야 하므로 역할 구분을 사용하여 수행할 수 없습니다. 키로 암호화된 열이 포함된 테이블이 회전되는 경우 열 암호화 키를 회전하는 데 시간이 오래 걸릴 수 있습니다. 따라서 조직에서는 열 암호화 키 회전을 신중하게 계획해야 합니다.

오프라인 또는 온라인 방법을 사용하여 열 암호화 키를 회전할 수 있습니다. 오프라인 방식이 더 빠르지만 애플리케이션에서 영향을 받는 테이블에 쓸 수 없습니다. 후자의 접근 방식은 시간이 더 오래 걸릴 수 있지만 영향을 받은 테이블을 애플리케이션에서 사용할 수 없는 시간 간격을 제한할 수 있습니다. 자세한 내용은 PowerShellSet-SqlColumnEncryption과 함께 Always Encrypted를 사용하여 열 암호화 구성을 참조하세요.

Task 아티클 일반 텍스트 키/키 저장소에 액세스 데이터베이스에 액세스
1단계 PowerShell 환경을 시작하고 SqlServer 모듈을 가져옵니다. SqlServer 모듈 가져오기 없음 없음
2단계. 서버 및 데이터베이스에 연결합니다. 데이터베이스에 연결 없음
3단계: 열 마스터 키(순환할 열 암호화 키 보호)가 키 자격 증명 모음 또는 Azure Key Vault의 관리형 HSM에 저장되는 경우 Azure에 인증합니다. Connect-AzAccount 없음
4단계. 열 마스터 키가 Azure Key Vault에 저장된 경우 Azure Key Vault에 대한 액세스 토큰을 가져옵니다. Get-AzAccessToken 없음 없음
5단계. 새 열 암호화 키를 생성하고 열 마스터 키로 암호화하고 데이터베이스에 열 암호화 키 메타데이터를 만듭니다. New-SqlColumnEncryptionKey

참고: 내부적으로 열 암호화 키를 생성하고 암호화하는 cmdlet 변형을 사용합니다.
이 cmdlet은 아래에 CREATE COLUMN ENCRYPTION KEY(Transact-SQL) 문을 실행하여 키 메타데이터를 만듭니다.
6단계 이전 열 암호화 키로 암호화된 모든 열을 찾습니다. SMO(SQL Server 관리 개체) 프로그래밍 가이드 없음
7단계 영향을 받은 각 열에 대해 SqlColumnEncryptionSettings 개체를 만듭니다. SqlColumnEncryptionSettings는 메모리(PowerShell)에 있는 개체입니다. 열의 대상 암호화 체계를 지정합니다. 이 경우 개체는 영향을 받은 열을 새 열 암호화 키를 사용하여 암호화해야 하므로 지정해야 합니다. New-SqlColumnEncryptionSettings 없음 없음
8단계: 새 열 암호화 키를 사용하여 5단계에서 식별된 열을 다시 암호화합니다. Set-SqlColumnEncryption

참고: 이 단계는 시간이 오래 걸릴 수 있습니다. 애플리케이션은 선택한 방법(온라인 및 오프라인)에 따라 전체 작업 또는 일부 작업을 통해 테이블에 액세스할 수 없습니다.
9단계. 이전 열 암호화 키에 대한 메타데이터를 제거합니다. Remove-SqlColumnEncryptionKey 없음

예제 - 열 암호화 키 회전

아래 스크립트는 열 암호화 키를 회전하는 방법을 보여 줍니다. 스크립트는 대상 데이터베이스에 CEK1이라는 열 암호화 키(순환할 열)로 암호화된 일부 열이 포함되어 있다고 가정합니다. 이 열은 CMK1이라는 열 마스터 키를 사용하여 보호됩니다(열 마스터 키는 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"
$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

다음 단계

참고 항목