AlwaysEncrypted Column使用CNG密钥 - 加密列加密密钥可能已损坏

时间:2017-10-11 04:23:29

标签: sql-server powershell encryption cryptography sql-server-2016

设置:我正在尝试从加密列中读取数据

  • 始终在服务器A上为其托管的本地sql实例设置了加密列(我知道它违背了AE的目的,但这仅用于测试)
  • 现在我尝试通过首先从服务器A导出CNG密钥并将其导入服务器B并重新创建具有相同配置和名称的CNG密钥来解密来自服务器B的数据,但我收到此错误时我尝试从服务器B读取数据:

    Msg 0, Level 11, State 0, Line 0
    Failed to decrypt column 'Name'.
    Msg 0, Level 11, State 0, Line 0
    Failed to decrypt a column encryption key using key store provider: 'MSSQL_CNG_STORE'. Verify the properties of the column encryption key and its column master key in your database. The last 10 bytes of the encrypted column encryption key are: 'U3-2A-2V-2D-F5-03-C7-C9-4A-C4'.
    Msg 0, Level 11, State 0, Line 0
    The specified encrypted column encryption key signature does not match the signature computed with the column master key (asymmetric key) in 'Microsoft Software Key Storage Provider/AE_CNG_PS_test'. The encrypted column encryption key may be corrupt, or the specified path may be incorrect.
    Parameter name: encryptedColumnEncryptionKey
    

代码如下:

@Server A

  • 创建主密钥和加密密钥的CNG密钥创建

    # Create a column master key in a key store that has a CNG provider, a.k.a key store provider (KSP).
    $cngProviderName = "Microsoft Software Key Storage Provider" # If you have an HSM, you can use a KSP for your HSM instead of a Microsoft KSP
    $cngAlgorithmName = "RSA"
    $cngKeySize = 2048 # Recommended key size for Always Encrypted column master keys
    $cngKeyName = "AE_CNG_PS_test" # Name identifying your new key in the KSP
    $cngProvider = New-Object System.Security.Cryptography.CngProvider($cngProviderName)
    $cngKeyParams = New-Object System.Security.Cryptography.CngKeyCreationParameters
    $cngKeyParams.provider = $cngProvider
    $cngKeyParams.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::OverwriteExistingKey
    $keySizeProperty = New-Object System.Security.Cryptography.CngProperty("Length", [System.BitConverter]::GetBytes($cngKeySize), [System.Security.Cryptography.CngPropertyOptions]::None);
    $cngKeyParams.Parameters.Add($keySizeProperty)
    $cngAlgorithm = New-Object System.Security.Cryptography.CngAlgorithm($cngAlgorithmName)
    $cngKey = [System.Security.Cryptography.CngKey]::Create($cngAlgorithm, $cngKeyName, $cngKeyParams)
    
  • 导出CNG密钥

    [byte]$PubKey = $cngKey.Export([System.Security.Cryptography.CngKeyBlobFormat]::GenericPublicBlob)
    [String]$ExpPubKey = [Convert]::ToBase64String($PubKey)
    $ExpPubKey | Out-File C:\FakePath\PubKey.txt
    ## C:\FakePath\PubKey.txt = UlNasasdasgerferferferfsASIurh34e23t23gSgzxkTFTuFpPYlTzYAYuurypos6nutcXg5Ek4wXQ/JsDLAXXcKxTYl/SBo490b1QP303rwXsdgU67Hy67aXrhywCO9BjzXAEf0qJDLqt3r7RAUByrSaUg1Jp2RrdTb7uS6Vf8bDYmwDDSfqQbEHkm2fA36diLGDxQ==
    
  • 服务器A的CNG密钥

    PS C:\Users\Test> $cngKey
    AlgorithmGroup     : RSA
    Algorithm          : RSA
    ExportPolicy       : None
    Handle             : Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle
    IsEphemeral        : False
    IsMachineKey       : False
    KeyName            : AE_CNG_PS_test
    KeySize            : 2048
    KeyUsage           : AllUsages
    ParentWindowHandle : 0
    Provider           : Microsoft Software Key Storage Provider
    ProviderHandle     : Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle
    UniqueName         : va9356ed810cc3dg272b6a921g53daad_b13750ab-b64d-4234-aff4-1ffs23593b6fca
    UIPolicy           : System.Security.Cryptography.CngUIPolicy
    

@Server B

  • 导入CNG密钥

    [string]$ImpPubKey = 'UlNasasdasgerferferferfsASIurh34e23t23gSgzxkTFTuFpPYlTzYAYuurypos6nutcXg5Ek4wXQ/JsDLAXXcKxTYl/SBo490b1QP303rwXsdgU67Hy67aXrhywCO9BjzXAEf0qJDLqt3r7RAUByrSaUg1Jp2RrdTb7uS6Vf8bDYmwDDSfqQbEHkm2fA36diLGDxQ=='
    $ImpBlob = [Convert]::FromBase64String($ImpPubKey)
    $cngKey = [System.Security.Cryptography.CngKey]::Import($ImpBlob,[System.Security.Cryptography.CngKeyBlobFormat]::GenericPublicBlob)
    $cngKeyParams = New-Object System.Security.Cryptography.CngKeyCreationParameters
    $cngKeyParams.provider = $cngKey.Provider
    $cngKeyParams.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::OverwriteExistingKey
    $keySizeProperty = New-Object System.Security.Cryptography.CngProperty("Length", [System.BitConverter]::GetBytes($cngKey.KeySize), [System.Security.Cryptography.CngPropertyOptions]::None);
    $cngKeyParams.Parameters.Add($keySizeProperty)
    
    $NewlyCreatedCNGFromImport = [System.Security.Cryptography.CngKey]::Create($cngKey.Algorithm,'AE_CNG_PS_test',$cngKeyParams)
    
  • CNG用于服务器B中新创建的CNG

    PS C:\Users\Test> $NewlyCreatedCNGFromImport
    
    AlgorithmGroup     : RSA
    Algorithm          : RSA
    ExportPolicy       : None
    Handle             : Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle
    IsEphemeral        : False
    IsMachineKey       : False
    KeyName            : AE_CNG_PS_test
    KeySize            : 2048
    KeyUsage           : AllUsages
    ParentWindowHandle : 0
    Provider           : Microsoft Software Key Storage Provider
    ProviderHandle     : Microsoft.Win32.SafeHandles.SafeNCryptProviderHandle
    UniqueName         : a25ag6356ed810c3fd472shees121ea4daad_f023yd98-44V3-75G7-819b-02cf6d3t5470
    UIPolicy           : System.Security.Cryptography.CngUIPolicy
    

似乎当我从服务器B读取服务器A的数据时,SQL无法使用导入的CNG密钥查找或解密该列。这可能是路径的问题吗?或CNG密钥的导出/导入(+在服务器B中重新创建)出现问题?

0 个答案:

没有答案