자습서: 보안 enclave를 사용한 Always Encrypted를 이용하여 .NET Framework 애플리케이션 개발

적용 대상: SQL Server 2019(15.x) 이상 - Windows 전용 Azure SQL Database

이 자습서에서는 보안 enclave를 사용하여 Always Encrypted에 대한 서버 쪽 보안 Enclave를 사용하는 데이터베이스 쿼리를 발급하는 애플리케이션을 개발하는 방법을 설명합니다.

참고 항목

.NET Framework는 증명 없이 VBS enclave와 함께 Always Encrypted 사용을 지원하지 않습니다. 이 자습서는 Microsoft Azure Attestation(Azure SQL Database의 Intel SGX enclave 사용) 또는 호스트 보호 서비스(SQL Server의 VBS Enclave 포함)에서 증명을 사용하는 경우에만 적용됩니다.

전제 조건

이 자습서의 아래 단계를 따르기 전에 보안 Enclave 자습서에서 Always Encrypted 사용을 시작하는 중 하나를 완료했는지 확인합니다.

또한 Visual Studio(버전 2022 권장) - 에서 https://visualstudio.microsoft.com/다운로드해야 합니다. 애플리케이션 개발 컴퓨터는 .NET Framework 4.7.2 이상을 실행해야 합니다.

1단계: Visual Studio 프로젝트 설정

.NET Framework 애플리케이션에서 보안 Enclave와 함께 Always Encrypted를 사용하려면 애플리케이션이 .NET Framework 4.7.2에 대해 빌드되고 Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders NuGet통합되어 있는지 확인해야 합니다. 또한 Azure Key Vault에 열 마스터 키를 저장하는 경우 애플리케이션을 Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider NuGet 버전 2.4.0 이상과 통합해야 합니다.

  1. Visual Studio를 엽니다.

  2. 새 C# 콘솔 앱(.NET Framework) 프로젝트를 만듭니다.

  3. 프로젝트가 .NET Framework 4.7.2 이상을 대상으로 하는지 확인합니다. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택한 후 대상 프레임워크를 .NET Framework 4.7.2로 설정합니다.

  4. 도구(주 메뉴) >NuGet 패키지 관리자>패키지 관리자 콘솔로 이동하여 다음 NuGet 패키지를 설치합니다. 패키지 관리자 콘솔에서 다음 코드를 실행합니다.

    Install-Package Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders -IncludePrerelease
    
  5. 열 마스터 키를 저장하는 데 Azure Key Vault를 사용하는 경우 도구(주 메뉴) >NuGet 패키지 관리자>패키지 관리자 콘솔로 이동하여 다음 NuGet 패키지를 설치합니다. 패키지 관리자 콘솔에서 다음 코드를 실행합니다.

    Install-Package Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider -IncludePrerelease -Version 2.4.0
    Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
    
  6. 프로젝트의 App.config 파일을 엽니다.

  7. <configuration> 섹션을 찾아 <configSections> 섹션을 추가하거나 업데이트합니다.

    1. <configuration> 섹션에 <configSections> 섹션이 포함되어 있지 않는 경우 <configuration> 바로 아래에 다음 콘텐츠를 추가합니다.

      <configSections>
        <section name="SqlColumnEncryptionEnclaveProviders" type="System.Data.SqlClient.SqlColumnEncryptionEnclaveProviderConfigurationSection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </configSections>
      
    2. <configuration> 섹션에 이미 <configSections> 섹션이 있는 경우 <configSections> 섹션 내에 다음 줄을 추가합니다.

      <section name="SqlColumnEncryptionEnclaveProviders"  type="System.   Data.SqlClient.   SqlColumnEncryptionEnclaveProviderConfigurationSection, System.   Data,  Version=4.0.0.0, Culture=neutral,    PublicKeyToken=b77a5c561934e089" />
      
  8. <configuration> 아래 </configSections>섹션 내에서 서버 쪽 보안 Enclave를 증명하고 상호 작용하는 데 사용할 enclave 공급자를 지정하는 새 섹션을 추가합니다.

    1. SQL Server 및 HGS(호스트 보호 서비스)를 사용하는 경우(자습서에서 데이터베이스 사용: SQL Server보안 Enclave를 사용하여 Always Encrypted 사용 시작) 아래 섹션을 추가합니다.

      <SqlColumnEncryptionEnclaveProviders>
        <providers>
          <add name="VBS"  type="Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.HostGuardianServiceEnclaveProvider,  Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders,    Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
        </providers>
      </SqlColumnEncryptionEnclaveProviders>
      

      다음은 간단한 콘솔 애플리케이션에 대한 app.config 파일의 전체 예제입니다.

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
        <configSections>
          <section name="SqlColumnEncryptionEnclaveProviders" type="System.Data.SqlClient.SqlColumnEncryptionEnclaveProviderConfigurationSection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </configSections>
        <SqlColumnEncryptionEnclaveProviders>
          <providers>
            <add name="VBS"  type="Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.HostGuardianServiceEnclaveProvider,  Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders,    Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
          </providers>
        </SqlColumnEncryptionEnclaveProviders>
        <startup> 
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
        </startup>
      </configuration>
      
    2. SGX enclave 및 Microsoft Azure Attestation에서 Azure SQL Database를 사용하는 경우(자습서에서 데이터베이스 사용: Azure SQL Database에서 보안 Intel SGX enclave로 Always Encrypted 시작) 아래 섹션을 추가합니다.

      <SqlColumnEncryptionEnclaveProviders>
        <providers>
          <add name="SGX" type="Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.AzureAttestationEnclaveProvider, Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders, Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
        </providers>
      </SqlColumnEncryptionEnclaveProviders>
      

      다음은 간단한 콘솔 애플리케이션에 대한 app.config 파일의 전체 예제입니다.

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
        <configSections>
          <section name="SqlColumnEncryptionEnclaveProviders" type="System.Data.SqlClient.SqlColumnEncryptionEnclaveProviderConfigurationSection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </configSections>
        <SqlColumnEncryptionEnclaveProviders>
          <providers>
            <add name="SGX" type="Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.AzureAttestationEnclaveProvider, Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders, Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
          </providers>
        </SqlColumnEncryptionEnclaveProviders>
        <startup> 
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
        </startup>
      </configuration>
      

2단계: 애플리케이션 논리 구현

애플리케이션은 자습서 중 하나에서 만든 ContosoHR 데이터베이스에 연결하고 필수 구성 요소를 참조하며 SSN 열의 조건자와 Salary 열의 범위 비교가 포함된 LIKE 쿼리를 실행합니다.

  1. Program.cs 파일의 내용(Visual Studio에서 생성됨)을 아래 코드로 바꿉니다. 서버 이름, 데이터베이스 인증 설정 및 환경에 대한 Enclave 증명 URL로 데이터베이스 연결 문자열을 업데이트합니다.

    using System;
    using System.Data.SqlClient;
    using System.Data;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                string connectionString = "Data Source = myserver; Initial Catalog = ContosoHR; Column Encryption Setting = Enabled;Enclave Attestation Url = http://hgs.bastion.local/Attestation; Integrated Security = true";
    
                //string connectionString = "Data Source = myserver.database.windows.net; Initial Catalog = ContosoHR; Column Encryption Setting = Enabled;Enclave Attestation Url = https://myattestationprovider.uks.attest.azure.net/attest/SgxEnclave; User ID=user; Password=password";
    
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    connection.Open();
    
                    SqlCommand cmd = connection.CreateCommand();
                    cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [Salary] FROM [HR].[Employees] WHERE [SSN] LIKE @SSNPattern AND [Salary] > @MinSalary;";
    
                    SqlParameter paramSSNPattern = cmd.CreateParameter();
    
                    paramSSNPattern.ParameterName = @"@SSNPattern";
                    paramSSNPattern.DbType = DbType.AnsiStringFixedLength;
                    paramSSNPattern.Direction = ParameterDirection.Input;
                    paramSSNPattern.Value = "%9838";
                    paramSSNPattern.Size = 11;
    
                    cmd.Parameters.Add(paramSSNPattern);
    
                    SqlParameter MinSalary = cmd.CreateParameter();
    
                    MinSalary.ParameterName = @"@MinSalary";
                    MinSalary.DbType = DbType.Currency;
                    MinSalary.Direction = ParameterDirection.Input;
                    MinSalary.Value = 20000;
    
                    cmd.Parameters.Add(MinSalary);
                    cmd.ExecuteNonQuery();
    
                    SqlDataReader reader = cmd.ExecuteReader();
                    while (reader.Read())
    
                    {
                        Console.WriteLine(reader[0] + ", " + reader[1] + ", " + reader[2] + ", " + reader[3]);
                    }   
                    Console.ReadKey();
                }
            }
        }
    }
    
  2. 애플리케이션을 빌드 및 실행합니다.

참고 항목