다음을 통해 공유


Blob에 대한 클라이언트 쪽 암호화

.NET용 Azure Blob Storage 클라이언트 라이브러리는 Azure Storage에 업로드하기 전에 클라이언트 애플리케이션 내에서 데이터를 암호화하고, 클라이언트에 다운로드하는 동안 데이터의 암호를 해독하도록 지원합니다. 라이브러리 또한 스토리지 계정 키 관리를 위해 Azure Key Vault와의 통합을 지원합니다.

Important

Blob Storage는 서비스 쪽 암호화 및 클라이언트 쪽 암호화를 모두 지원합니다. 대부분의 시나리오에서 데이터를 쉽게 보호할 수 있도록 서비스 쪽 암호화 기능을 사용하는 것이 좋습니다. 서비스 쪽 암호화에 대한 자세한 내용은 미사용 데이터에 대한 Azure Storage 암호화를 참조하세요.

클라이언트 쪽 암호화와 Azure Key Vault를 사용하여 Blob을 암호화하는 프로세스를 안내하는 단계별 자습서는 Azure Key Vault를 사용하여 Microsoft Azure Storage에서 Blob 암호화 및 해독을 참조하세요.

클라이언트 쪽 암호화 정보

Azure Blob Storage 클라이언트 라이브러리는 AES(Advanced Encryption Standard)를 사용하여 사용자 데이터를 암호화합니다. 클라이언트 라이브러리에서 사용할 수 있는 클라이언트 쪽 암호화에는 두 가지 버전이 있습니다.

Warning

클라이언트 라이브러리의 CBC 모드 구현에 있는 보안 취약성으로 인해 클라이언트 쪽 암호화 버전 1을 더 이상 사용하지 않는 것이 좋습니다. 이 보안 취약성에 대한 자세한 내용은 보안 취약성을 해결하기 위해 SDK에서 클라이언트 쪽 암호화를 업데이트하는 Azure Storage를 참조하세요. 현재 버전 1을 사용하는 경우 버전 2를 사용하도록 애플리케이션을 업데이트하고 데이터를 마이그레이션하는 것이 좋습니다. 추가 지침은 애플리케이션의 보안 취약성 완화 섹션을 참조하세요.

애플리케이션의 보안 취약성 완화

Blob Storage 클라이언트 라이브러리의 CBC 모드 구현에서 검색된 보안 취약성으로 인해 다음 작업 중 하나 이상을 즉시 수행하는 것이 좋습니다.

  • 클라이언트 쪽 암호화 대신 서비스 쪽 암호화 기능을 사용하는 것이 좋습니다. 서비스 쪽 암호화 기능에 대한 자세한 내용은 미사용 데이터에 대한 Azure Storage 암호화를 참조하세요.

  • 클라이언트 쪽 암호화를 사용해야 하는 경우 애플리케이션을 클라이언트 쪽 암호화 v1에서 클라이언트 쪽 암호화 v2로 마이그레이션합니다.

다음 표에서는 애플리케이션을 클라이언트 쪽 암호화 v2로 마이그레이션하도록 선택하는 경우 수행할 단계를 요약합니다.

클라이언트 쪽 암호화 상태 권장 조치
애플리케이션에서 클라이언트 쪽 암호화 v1만 지원하는 클라이언트 라이브러리 버전을 통해 클라이언트 쪽 암호화를 사용합니다. 클라이언트 쪽 암호화 v2를 지원하는 클라이언트 라이브러리 버전을 사용하도록 애플리케이션을 업데이트합니다. 지원되는 버전 목록은 클라이언트 쪽 암호화에 대한 SDK 지원 매트릭스를 참조하세요. 자세한 정보...

클라이언트 쪽 암호화 v2를 사용하도록 코드를 업데이트합니다. 자세한 정보...

암호화된 데이터를 다운로드하여 암호를 해독한 다음 클라이언트 쪽 암호화 v2로 다시 암호화합니다. 자세한 정보...
애플리케이션에서 클라이언트 쪽 암호화 v2를 지원하는 클라이언트 라이브러리 버전을 통해 클라이언트 쪽 암호화를 사용합니다. 클라이언트 쪽 암호화 v2를 사용하도록 코드를 업데이트합니다. 자세한 정보...

암호화된 데이터를 다운로드하여 암호를 해독한 다음 클라이언트 쪽 암호화 v2로 다시 암호화합니다. 자세한 정보...

또한 데이터를 보호하기 위해 다음 단계를 수행하는 것이 좋습니다.

  • 프라이빗 엔드포인트를 사용하도록 스토리지 계정을 구성하여 프라이빗 링크를 통해 VNet(가상 네트워크)과 스토리지 계정 간의 모든 트래픽을 보호합니다. 자세한 내용은 Azure Storage에 프라이빗 엔드포인트 사용을 참조하세요.
  • 네트워크 액세스를 특정 네트워크로만 제한합니다.

클라이언트 쪽 암호화에 대한 SDK 지원 매트릭스

다음 표에서는 .NET, Java 및 Python용 클라이언트 라이브러리의 버전이 다른 버전의 클라이언트 쪽 암호화를 지원하는지 보여줍니다.

.NET Java Python
클라이언트 쪽 암호화 v2 및 v1 버전 12.13.0 이상 버전 12.18.0 이상 버전 12.13.0 이상
클라이언트 쪽 암호화 v1만 버전 12.12.0 이하 버전 12.17.0 이하 버전 12.12.0 이하

참고 항목

클라이언트 쪽 암호화 v2.1은 버전 12.27.0 이상용 Java SDK에서 사용할 수 있습니다. 이 버전을 사용하면 인증된 암호화에 대한 지역 길이를 16바이트에서 1GiB로 구성할 수 있습니다. 자세한 내용은 예제: 클라이언트 쪽 암호화 v2를 사용하여 Blob 암호화 및 암호 해독의 Java 예제를 참조하세요.

애플리케이션에서 이전 버전의 .NET, Java 또는 Python 클라이언트 라이브러리를 통해 클라이언트 쪽 암호화를 사용하는 경우 먼저 코드를 클라이언트 쪽 암호화 v2를 지원하는 버전으로 업그레이드해야 합니다. 다음으로 클라이언트 쪽 암호화 v2를 사용하여 데이터의 암호를 해독하고 다시 암호화해야 합니다. 필요한 경우 코드를 마이그레이션하는 동안 이전 버전의 클라이언트 라이브러리를 통해 클라이언트 쪽 암호화 v2를 지원하는 클라이언트 라이브러리 버전을 사용할 수 있습니다. 코드 예제는 예제: 클라이언트 쪽 암호화 v2를 사용하여 Blob 암호화 및 암호 해독을 참조하세요.

클라이언트 쪽 암호화의 작동 방식

Azure Blob Storage 클라이언트 라이브러리는 봉투 암호화를 사용하여 클라이언트 쪽의 데이터를 암호화하고 암호 해독합니다. 봉투 암호화는 하나 이상의 추가 키를 사용하여 키를 암호화합니다.

Blob Storage 클라이언트 라이브러리는 Azure Key Vault를 사용하여 클라이언트 쪽 암호화에 사용되는 키를 보호합니다. Azure Key Vault에 대한 자세한 내용은 Azure Key Vault란?을 참조하세요.

봉투(Envelope) 기술을 통해 암호화 및 암호 해독

봉투 기술을 통한 암호화의 작동 방식은 다음과 같습니다.

  1. Azure Storage 클라이언트 라이브러리에서 일회용 대칭 키인 CEK(콘텐츠 암호화 키)를 생성합니다.

  2. 사용자 데이터가 CEK를 사용하여 암호화됩니다.

  3. 그런 다음 키 암호화 KEK를 사용하여 CEK를 래핑(암호화)합니다. KEK는 키 식별자로 식별되고 비대칭 키 쌍 또는 대칭 키가 될 수 있습니다. KEK는 로컬로 관리하거나 Azure Key Vault에 저장할 수 있습니다.

    Azure Storage 클라이언트 라이브러리 자체는 KEK에 액세스할 수 없습니다. 라이브러리는 자격 증명 모음에서 제공되는 키 래핑 알고리즘을 호출합니다. 사용자는 원하는 경우 키 래핑/래핑 해제를 위해 사용자 지정 공급자를 사용하도록 선택할 수 있습니다.

  4. 그런 다음, 암호화된 데이터가 Azure Blob Storage에 업로드됩니다. 일부 추가 암호화 메타데이터와 함께 래핑된 키는 메타데이터로 Blob에 저장됩니다.

봉투 기술을 통한 암호 해독의 작동 방식은 다음과 같습니다.

  1. Azure Storage 클라이언트 라이브러리에서 사용자가 KEK를 로컬로 또는 Azure Key Vault에서 관리한다고 가정합니다. 사용자는 암호화에 사용된 특정 키를 알 필요가 없습니다. 대신 다른 키 식별자를 키로 확인하는 키 확인자를 설정하여 사용할 수 있습니다.
  2. 클라이언트 라이브러리에서 Azure Storage에 저장된 암호화 자료와 함께 암호화된 데이터를 다운로드합니다.
  3. 그런 다음, 래핑된 CEK가 KEK를 사용하여 래핑 해제(암호 해독)됩니다. 클라이언트 라이브러리는 이 프로세스 중에 KEK에 액세스할 수 없지만 Azure Key Vault 또는 다른 키 저장소의 래핑 해제 알고리즘만 호출합니다.
  4. 클라이언트 라이브러리에서 CEK를 사용하여 암호화된 사용자 데이터의 암호를 해독합니다.

Blob 업로드/다운로드 시 암호화/암호 해독

Blob Storage 클라이언트 라이브러리는 업로드할 때만 전체 Blob의 암호화를 지원합니다. 다운로드는 전체 및 범위 다운로드가 모두 지원됩니다. 클라이언트 쪽 암호화 v2는 데이터를 전체로만 변환할 수 있는 4MiB 버퍼링된 인증된 암호화 블록으로 청크합니다. 청크 크기를 조정하려면 클라이언트 쪽 암호화 v2.1을 지원하는 최신 버전의 SDK를 사용하고 있는지 확인합니다. 영역 길이는 16바이트부터 최대 1GiB까지 구성할 수 있습니다.

암호화하는 동안 클라이언트 라이브러리는 16바이트의 임의 IV(초기화 벡터) 및 32바이트의 임의 CEK를 생성하고, 이 정보를 사용하여 Blob 데이터의 봉투 암호화를 수행합니다. 그런 다음, 래핑된 CEK 및 일부 추가 암호화 메타데이터가 암호화된 Blob과 함께 Blob 메타데이터로 저장됩니다.

클라이언트에서 전체 Blob을 다운로드하면 래핑된 CEK가 래핑 해제되고 IV와 함께 사용되어 암호 해독된 데이터를 클라이언트에 반환합니다.

암호화된 Blob에서 임의의 범위를 다운로드하려면 사용자가 제공한 범위를 조정하여 요청된 범위를 성공적으로 해독하는 데 사용할 수 있는 소량의 추가 데이터를 가져옵니다.

이 스키마를 사용하여 모든 blob 유형(블록 blob, 페이지 blob 및 추가 blob)을 암호화/암호 해독할 수 있습니다.

Warning

Blob에 대한 사용자 고유의 메타데이터를 편집하거나 업로드하는 경우 암호화 메타데이터가 유지되는지 확인해야 합니다. 암호화 메타데이터도 유지하지 않고 새 메타데이터를 업로드하면 래핑된 CEK, IV 및 기타 메타데이터가 손실되고 Blob의 콘텐츠를 검색할 수 없습니다. Set Blob Metadata(Blob 메타데이터 설정) 작업을 호출하면 항상 모든 Blob 메타데이터가 바뀝니다.

암호화된 Blob에서 읽거나 쓰는 경우 전체 Blob 업로드 명령(예: Put Blob(Blob 배치)) 범위 또는 전체 Blob 다운로드 명령(예: Get Blob(Blob 가져오기))을 사용합니다. Put Block(블록 배치), Put Block List(블록 목록 배치), Put Page(페이지 배치) 또는 Append Block(블록 추가)와 같은 프로토콜 작업을 사용하여 암호화된 Blob에 쓰지 마세요. 암호화된 Blob에서 이러한 작업을 호출하면 해당 Blob이 손상되어 읽을 수 없게 될 수 있습니다.

예제: 클라이언트 쪽 암호화 v2를 사용하여 Blob 암호화 및 암호 해독

이 섹션의 코드 예제에서는 클라이언트 쪽 암호화 v2를 사용하여 Blob을 암호화하고 암호 해독하는 방법을 보여 줍니다.

Important

이전에 클라이언트 쪽 암호화 v1로 암호화된 데이터가 있는 경우 해당 데이터의 암호를 해독하고 클라이언트 쪽 암호화 v2로 다시 암호화해야 합니다. 아래의 클라이언트 라이브러리에 대한 지침 및 샘플을 참조하세요.

.NET 코드에서 클라이언트 쪽 암호화를 사용하려면 Blob Storage 클라이언트 라이브러리를 참조하세요. 버전 12.13.0 이상을 사용하고 있는지 확인합니다. 버전 11.x에서 버전 12.13.0으로 마이그레이션해야 하는 경우 마이그레이션 가이드를 참조하세요.

클라이언트 쪽 암호화를 위한 Azure Key Vault 통합에는 다음 두 개의 추가 패키지가 필요합니다.

  • Azure.Core 패키지는 IKeyEncryptionKeyIKeyEncryptionKeyResolver 인터페이스를 제공합니다. .NET용 Blob Storage 클라이언트 라이브러리는 이미 이 어셈블리를 종속성으로 정의하고 있습니다.

  • Azure.Security.KeyVault.Keys 패키지(버전 4.x 이상)는 클라이언트 쪽 암호화에 사용되는 Key Vault REST 클라이언트 및 암호화 클라이언트를 제공합니다. Azure Key Vault를 키 저장소로 사용하는 경우 이 패키지가 프로젝트에서 참조되는지 확인합니다.

    Azure Key Vault는 높은 가치의 마스터 키용으로 설계되었으며, 키 자격 증명 모음당 제한은 이 디자인을 반영하고 있습니다. Azure.Security.KeyVault.Keys 버전 4.1.0부터 IKeyEncryptionKeyResolver 인터페이스는 키 캐싱을 지원하지 않습니다. 제한으로 인해 캐싱이 필요한 경우 이 샘플에서 설명하는 방법을 사용하여 캐싱 레이어를 Azure.Security.KeyVault.Keys.Cryptography.KeyResolver 인스턴스에 삽입할 수 있습니다.

개발자는 키, 키 확인자 또는 키 및 키 확인자 모두를 제공할 수 있습니다. 키는 CEK 래핑 및 래핑 해제 논리를 제공하는 키 식별자를 사용하여 식별됩니다. 키 확인자는 암호 해독 프로세스 중에 키를 확인하는 데 사용됩니다. 키 확인자는 키 식별자가 지정된 키를 반환하는 확인 메서드를 정의합니다. 확인자는 사용자에게 여러 위치에서 관리되는 여러 키 중에서 선택할 수 있는 기능을 제공합니다.

암호화에서 키는 항상 사용되며 키가 없으므로 오류가 발생합니다.

암호 해독할 때 키가 지정되고 해당 식별자가 필요한 키 식별자와 일치하면 해당 키가 암호 해독에 사용됩니다. 그렇지 않으면 클라이언트 라이브러리에서 확인자를 호출하려고 시도합니다. 확인자가 지정되지 않으면 클라이언트 라이브러리에서 오류를 throw합니다. 확인자가 지정되면 키를 가져오기 위해 키 확인자가 호출됩니다. 확인자가 지정되었지만 키 식별자에 대한 매핑이 없으면 클라이언트 라이브러리에서 오류를 throw합니다.

클라이언트 쪽 암호화를 사용하려면 ClientSideEncryptionOptions 개체를 만들고, 클라이언트를 만들 때 SpecializedBlobClientOptions를 사용하여 해당 개체를 설정합니다. 암호화 옵션은 API별로 설정할 수 없습니다. 다른 모든 항목은 내부적으로 클라이언트 라이브러리에 의해 처리됩니다.

// Your key and key resolver instances, either through Azure Key Vault SDK or an external implementation.
IKeyEncryptionKey key;
IKeyEncryptionKeyResolver keyResolver;

// Create the encryption options to be used for upload and download.
ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0)
{
   KeyEncryptionKey = key,
   KeyResolver = keyResolver,
   // String value that the client library will use when calling IKeyEncryptionKey.WrapKey()
   KeyWrapAlgorithm = "some algorithm name"
};

// Set the encryption options on the client options.
BlobClientOptions options = new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions };

// Create blob client with client-side encryption enabled.
// Client-side encryption options are passed from service clients to container clients, 
// and from container clients to blob clients.
// Attempting to construct a BlockBlobClient, PageBlobClient, or AppendBlobClient from a BlobContainerClient
// with client-side encryption options present will throw, as this functionality is only supported with BlobClient.
BlobClient blob = new BlobServiceClient
(new Uri($"https://{accountName}.blob.core.windows.net"), new DefaultAzureCredential(), options).GetBlobContainerClient("my-container").GetBlobClient("myBlob");

// Upload the encrypted contents to the blob.
blob.Upload(stream);

// Download and decrypt the encrypted contents from the blob.
MemoryStream outputStream = new MemoryStream();
blob.DownloadTo(outputStream);

암호화 옵션은 BlobClientOptions 개체를 허용하는 BlobServiceClient, BlobContainerClient 또는 BlobClient 생성자에 적용할 수 있습니다.

BlobClient 개체가 이미 코드에 있지만 클라이언트 쪽 암호화 옵션이 없는 경우 지정된 ClientSideEncryptionOptions를 사용하여 해당 개체의 복사본을 만드는 확장 메서드를 사용할 수 있습니다. 해당 확장 메서드는 새 BlobClient 개체를 처음부터 생성하는 오버 헤드를 방지합니다.

using Azure.Storage.Blobs.Specialized;

// An existing BlobClient instance and encryption options.
BlobClient plaintextBlob;
ClientSideEncryptionOptions encryptionOptions;

// Get a copy of the blob that uses client-side encryption.
BlobClient clientSideEncryptionBlob = plaintextBlob.WithClientSideEncryptionOptions(encryptionOptions);

클라이언트 쪽 암호화 v2를 사용하도록 코드를 업데이트한 후 클라이언트 쪽 암호화 v2를 사용하여 이전에 암호화된 데이터를 다시 암호화하는 데 설명된 대로 기존 암호화된 데이터의 암호를 해독하고 다시 암호화해야 합니다.

클라이언트 쪽 암호화 v2를 사용하여 이전에 암호화된 데이터 다시 암호화

이전에 클라이언트 쪽 암호화 v1로 암호화된 모든 데이터는 암호 해독된 다음 클라이언트 쪽 암호화 v2로 다시 암호화하여 보안 취약성을 완화해야 합니다. 암호 해독을 위해서는 데이터를 다운로드해야 하며 다시 암호화하려면 Blob Storage에 다시 업로드해야 합니다.

데이터를 클라이언트 쪽 암호화 v1에서 v2로 마이그레이션하는 방법 및 .NET에서 클라이언트 쪽 암호화 v2를 사용하여 데이터를 암호화하는 방법을 보여 주는 샘플 프로젝트는 암호화 마이그레이션 샘플 프로젝트를 참조하세요.

클라이언트 쪽 암호화 및 성능

스토리지 데이터를 암호화하면 추가 성능 오버헤드가 발생합니다. 애플리케이션에서 클라이언트 쪽 암호화를 사용하는 경우 클라이언트 라이브러리에서 CEK 및 IV를 안전하게 생성하고, 콘텐츠 자체를 암호화하고, 키 봉투를 위해 선택한 키 저장소와 통신하고, 추가 메타데이터의 형식을 지정하고 업로드해야 합니다. 이 오버헤드는 암호화되는 데이터의 양에 따라 달라집니다. 고객은 항상 개발 중에 애플리케이션 성능을 테스트하는 것이 좋습니다.

다음 단계