Учебник. Шифрование и расшифровка больших двоичных объектов с помощью хранилища ключей Azure

В этом руководстве вы узнаете, как использовать шифрование на стороне клиента для шифрования и расшифровки BLOB-объектов с помощью ключа, хранящегося в Azure Key Vault.

Хранилище BLOB-объектов Azure поддерживает шифрование на стороне службы и на стороне клиента. Для большинства сценариев корпорация Майкрософт рекомендует использовать функции шифрования на стороне службы, чтобы упростить защиту данных. Дополнительные сведения о шифровании на стороне службы см. в статье Шифрование Службы хранилища Azure для неактивных данных.

Клиентская библиотека Хранилище BLOB-объектов Azure для .NET поддерживает шифрование данных на стороне клиента в приложениях перед отправкой в служба хранилища Azure и расшифровку данных при скачивании на клиент. Библиотека также поддерживает интеграцию с Azure Key Vault для управления ключами.

В этом учебнике описаны следующие процедуры.

  • Настройка разрешений для ресурса Azure Key Vault
  • Создание консольного приложения для взаимодействия с ресурсами с помощью клиентских библиотек .NET
  • Добавление ключа в хранилище ключей
  • Настройка параметров шифрования на стороне клиента с помощью ключа, хранящегося в хранилище ключей
  • Создание клиентского объекта службы BLOB-объектов с включенным шифрованием на стороне клиента
  • Отправка зашифрованного большого двоичного объекта, а затем скачивание и расшифровка большого двоичного объекта

Необходимые компоненты

Назначение роли пользователю Microsoft Entra

При локальной разработке убедитесь, что учетная запись пользователя, доступ к хранилищу ключей, имеет правильные разрешения. Вам потребуется роль офицера шифрования Key Vault, чтобы создать ключ и выполнить действия по ключам в хранилище ключей. Роли Azure RBAC можно назначить пользователю с помощью портала Azure, Azure CLI или Azure PowerShell. Дополнительные сведения о доступных областях назначения ролей можно узнать на странице обзора области.

В этом сценарии вы назначите разрешения учетной записи пользователя, область в хранилище ключей, чтобы следовать принципу наименьших привилегий. В рамках этой практики пользователям предоставляются только минимальные необходимые разрешения, что позволяет создавать более защищенные рабочие среды.

В следующем примере показано, как назначить роль офицера шифрования Key Vault учетной записи пользователя, которая предоставляет доступ, который потребуется выполнить в этом руководстве.

Важно!

В большинстве случаев для распространения назначения ролей в Azure потребуется минута или две, но в редких случаях может потребоваться до восьми минут. Если при первом запуске кода возникают ошибки аутентификации, подождите несколько минут и повторите попытку.

  1. В портал Azure найдите хранилище ключей с помощью основной панели поиска или левой навигации.

  2. На странице обзора хранилища ключей выберите элемент управления доступом (IAM) в меню слева.

  3. На странице Контроль доступа (IAM) откройте вкладку Назначения ролей.

  4. Выберите + Добавить в верхнем меню, а затем выберите Добавить назначение роли в появившемся раскрывающемся меню.

    A screenshot showing how to assign a role in Azure portal.

  5. Используйте поле поиска, чтобы отфильтровать результаты для отображения нужной роли. В этом примере найдите сотрудника по шифрованию Key Vault и выберите соответствующий результат, а затем нажмите кнопку "Далее".

  6. В разделе Назначение доступа для выберите Пользователь, группа или субъект-служба и + Выбрать членов.

  7. В диалоговом окне найдите имя пользователя Microsoft Entra (обычно ваш user@domain адрес электронной почты), а затем выберите в нижней части диалогового окна.

  8. Нажмите кнопку Проверить и назначить, чтобы перейти на последнюю страницу, а затем еще раз Проверить и назначить, чтобы завершить процесс.

Настройка проекта

  1. В окне консоли (например, PowerShell или Bash) используйте dotnet new команду для создания консольного приложения с именем BlobEncryptionKeyVault. Эта команда создает простой проект "Hello World" на языке C# с одним файлом исходного кода Program.cs.

    dotnet new console -n BlobEncryptionKeyVault
    
  2. Перейдите в только что созданный каталог BlobEncryptionKeyVault .

    cd BlobEncryptionKeyVault
    
  3. Откройте проект в нужном редакторе кода. Чтобы открыть проект в:

    • Visual Studio, найдите и дважды щелкните файл BlobEncryptionKeyVault.csproj.
    • Visual Studio Code, выполните эту команду:
    code .
    

Чтобы взаимодействовать со службами Azure в этом примере, установите следующие клиентские библиотеки с помощью dotnet add package.

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Keys
dotnet add package Azure.Storage.Blobs

Добавьте следующие using директивы и добавьте ссылку на System.Configuration проект.

using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Security.KeyVault.Keys;
using Azure.Security.KeyVault.Keys.Cryptography;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

Настройка переменных среды

Это приложение ищет переменную среды, вызываемую KEY_VAULT_NAME для получения имени хранилища ключей. Чтобы задать переменную среды, откройте окно консоли и следуйте инструкциям операционной системы. Замените <your-key-vault-name> именем своего хранилища ключей.

Windows:

Переменные среды для Windows можно задать из командной строки. Однако при использовании этого подхода значения доступны всем приложениям, работающим в этой операционной системе, и могут привести к конфликтам, если вы не осторожны. Переменные среды можно задать на уровне пользователя или системы:

setx KEY_VAULT_NAME "<your-key-vault-name>"

После добавления переменной среды в Windows вам необходимо запустить новый экземпляр командного окна. Если вы используете Visual Studio в Windows, может потребоваться повторно запустить Visual Studio после создания переменной среды для обнаружения изменения.

Linux:

export KEY_VAULT_NAME=<your-key-vault-name>

Добавление ключа в Azure Key Vault

В этом примере мы создадим ключ и добавим его в хранилище ключей с помощью клиентской библиотеки Azure Key Vault. Вы также можете создать и добавить ключ в хранилище ключей с помощью Azure CLI, портал Azure или PowerShell.

В приведенном ниже примере мы создадим объект KeyClient для указанного хранилища. Затем KeyClient объект используется для создания нового ключа RSA в указанном хранилище.

var keyName = "testRSAKey";
var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");

// URI for the key vault resource
var keyVaultUri = $"https://{keyVaultName}.vault.azure.net";

TokenCredential tokenCredential = new DefaultAzureCredential();

// Create a KeyClient object
var keyClient = new KeyClient(new Uri(keyVaultUri), tokenCredential);

// Add a key to the key vault
var key = await keyClient.CreateKeyAsync(keyName, KeyType.Rsa);

Создание экземпляров сопоставителя ключей и ключей

Затем мы будем использовать ключ, который мы только что добавили в хранилище, чтобы создать экземпляры шифрования клиента и сопоставителя ключей. CryptographyClient реализует IKeyEncryptionKey и используется для выполнения криптографических операций с ключами, хранящимися в Azure Key Vault. KeyResolver реализует IKeyEncryptionResolver и извлекает ключи шифрования ключей из идентификатора ключа и разрешает ключ.

// Cryptography client and key resolver instances using Azure Key Vault client library
CryptographyClient cryptoClient = keyClient.GetCryptographyClient(key.Value.Name, key.Value.Properties.Version);
KeyResolver keyResolver = new (tokenCredential);

Если у вас есть существующий ключ в хранилище, с которым вы хотите зашифровать, можно создать экземпляры сопоставителя ключей и ключей, передав URI:

var keyVaultKeyUri = $"https://{keyVaultName}.vault.azure.net/keys/{keyName}";
CryptographyClient cryptoClient = new CryptographyClient(new Uri(keyVaultKeyUri), tokenCredential);

Настройка параметров шифрования

Теперь необходимо настроить параметры шифрования, которые будут использоваться для отправки и скачивания BLOB-объектов. Чтобы использовать шифрование на стороне клиента, сначала создадим ClientSideEncryptionOptions объект и задали его на создание SpecializedBlobClientOptionsклиента.

Класс ClientSideEncryptionOptions предоставляет параметры конфигурации клиента для подключения к BLOB-объектам служба хранилища с помощью шифрования на стороне клиента. KeyEncryptionKey требуется для операций отправки и используется для упаковки созданного ключа шифрования содержимого. KeyResolver требуется для операций загрузки и извлекает правильный ключ шифрования ключей, чтобы отменить скачанный ключ шифрования содержимого. KeyWrapAlgorithm требуется для отправки и указывает идентификатор алгоритма, используемый при оболочке ключа шифрования содержимого.

Важно!

Из-за уязвимости безопасности в версии 1 рекомендуется создать ClientSideEncryptionOptions объект, использующий ClientSideEncryptionVersion.V2_0 параметр версии. Дополнительные сведения об устранении уязвимости в приложениях см. в статье "Устранение уязвимостей безопасности в приложениях". Дополнительные сведения об этой уязвимости системы безопасности приведены в статье Обновление функции шифрования на стороне клиента в пакете SDK Службы хранилища Azure для устранения уязвимости системы безопасности.

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

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

Настройка клиентского объекта для использования шифрования на стороне клиента

В этом примере мы применяем параметры конфигурации шифрования на стороне клиента к объекту BlobServiceClient . При применении на уровне клиента службы эти параметры шифрования передаются из клиента службы в клиенты-контейнеры и от клиентов контейнеров к клиентам BLOB-объектов. BlobClient Когда объект выполняет операцию отправки или скачивания, клиентские библиотеки Хранилище BLOB-объектов Azure используют шифрование конверта для шифрования и расшифровки BLOB-объектов на стороне клиента. При использовании метода конверта ключ шифруется с помощью одного или нескольких дополнительных ключей.

// Create a blob client with client-side encryption enabled.
// 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.
Uri blobUri = new (string.Format($"https://{accountName}.blob.core.windows.net"));
BlobClient blob = new BlobServiceClient(blobUri, tokenCredential, options).GetBlobContainerClient("test-container").GetBlobClient("testBlob");

Шифрование и передача BLOB-объекта

BlobClient Когда объект вызывает метод отправки, выполняется несколько шагов для шифрования на стороне клиента:

  1. Клиентская библиотека служба хранилища Azure создает вектор случайной инициализации (IV) 16 байтов и случайный ключ шифрования содержимого (CEK) 32 байта и выполняет шифрование конверта данных BLOB-объектов с помощью этих сведений.
  2. Данные BLOB-объектов шифруются с помощью CEK.
  3. Затем CEK упаковывается (шифруется) с помощью ключа шифрования ключей (KEK), указанного в ClientSideEncryptionOptions. В этом примере KEK — это асимметричная пара ключей, хранящейся в указанном ресурсе Azure Key Vault. Клиент больших двоичных объектов никогда не имеет доступа к KEK, он просто вызывает алгоритм упаковки ключей, предоставляемый Key Vault.
  4. Затем зашифрованные данные BLOB-объектов передаются в учетную запись хранения.

Добавьте следующий код, чтобы зашифровать большой двоичный объект и отправить его в учетную запись хранения Azure:

// Upload the encrypted contents to the blob
Stream blobContent = BinaryData.FromString("Ready for encryption, Captain.").ToStream();
await blob.UploadAsync(blobContent);

После отправки большого двоичного объекта можно просмотреть большой двоичный объект в учетной записи хранения, чтобы просмотреть зашифрованное содержимое вместе с метаданными шифрования.

Расшифруйте BLOB-объект и загрузите его

Клиентская библиотека служба хранилища Azure предполагает, что пользователь управляет KEK локально или в хранилище ключей. Пользователь может не знать, какой именно ключ использовался для шифрования. Сопоставитель ключей, указанный в, ClientSideEncryptionOptions будет использоваться для разрешения идентификаторов ключей при скачивании и расшифровке данных BLOB-объектов.

При вызове BlobClient метода скачивания несколько шагов выполняются для расшифровки зашифрованных данных BLOB-объектов:

  1. Клиентская библиотека скачивает зашифрованные данные BLOB-объектов, включая метаданные шифрования, из учетной записи хранения.
  2. Затем оболочка CEK расшифровывается (расшифровывается) с помощью KEK. Клиентская библиотека не имеет доступа к KEK во время этого процесса, но вызывает только алгоритм распаковки ключа, указанный в ClientSideEncryptionOptions. Закрытый ключ пары ключей RSA остается в хранилище ключей, поэтому зашифрованный ключ из метаданных BLOB-объектов, содержащих CEK, отправляется в хранилище ключей для расшифровки.
  3. Клиентская библиотека использует CEK для расшифровки зашифрованных данных BLOB-объектов.

Добавьте следующий код для скачивания и расшифровки большого двоичного объекта, который вы ранее отправили.

// Download and decrypt the encrypted contents from the blob
Response<BlobDownloadInfo>  response = await blob.DownloadAsync();
BlobDownloadInfo downloadInfo = response.Value;
Console.WriteLine((await BinaryData.FromStreamAsync(downloadInfo.Content)).ToString());

Следующие шаги

В этом руководстве вы узнали, как использовать клиентские библиотеки .NET для выполнения шифрования на стороне клиента для операций отправки и скачивания BLOB-объектов.

Общие сведения о шифровании на стороне клиента для больших двоичных объектов, включая инструкции по переносу зашифрованных данных в версию 2, см. в разделе "Шифрование на стороне клиента" для больших двоичных объектов.

Дополнительные сведения о Azure Key Vault см. на странице обзора Azure Key Vault