Шифрование на стороне клиента для BLOB-объектов

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

Важно!

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

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

Сведения о шифровании на стороне клиента

Клиентская библиотека Хранилища BLOB-объектов Azure использует алгоритм AES для шифрования данных пользователя. В клиентской библиотеке доступны две версии шифрования на стороне клиента:

Предупреждение

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

Устранение уязвимости системы безопасности в приложениях

Из-за уязвимости системы безопасности, обнаруженной в реализации клиентской библиотеки Хранилища BLOB-объектов в режиме CBC, корпорация Майкрософт рекомендует немедленно выполнить одно или несколько следующих действий:

  • Рекомендуем использовать функции шифрования на стороне службы вместо функций шифрования на стороне клиента. Дополнительные сведения о шифровании на стороне службы см. в статье Шифрование Службы хранилища Azure для неактивных данных.

  • Если нужно использовать шифрование на стороне клиента, переведите приложения с шифрования на стороне клиента версии 1 на шифрование на стороне клиента версии 2.

В следующей таблице описаны действия, которые нужно выполнить, если вы решили перевести приложения на шифрование на стороне клиента версии 2:

Состояние шифрования на стороне клиента Рекомендованные действия
Для шифрования на стороне клиента приложение использует версию клиентской библиотеки, которая поддерживает только шифрование на стороне клиента версии 1. Обновите приложение для использования версии клиентской библиотеки, которая поддерживает шифрование на стороне клиента версии 2. Список поддерживаемых версий см. в разделе Таблица поддержки пакета SDK для шифрования на стороне клиента. Подробнее...

Обновите код для использования функции шифрования на стороне клиента версии 2. Подробнее...

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

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

Кроме того, корпорация Майкрософт рекомендует выполнить следующие действия для защиты данных:

  • Настройте учетные записи хранения для использования частных конечных точек для защиты всего трафика между виртуальной сетью и учетной записью хранения через приватный канал. Дополнительные сведения см. в статье Использование частных конечных точек для службы хранилища Azure.
  • Ограничьте сетевой доступ только определенными сетями.

Таблица поддержки пакета SDK для шифрования на стороне клиента

В следующей таблице показано, какие версии клиентских библиотек для .NET, Java и Python поддерживают функцию шифрования на стороне клиента и каких именно версий:

.NET Java Python
Шифрование на стороне клиента версий 1 и 2 Версии 12.13.0 и более поздние версии Версии 12.18.0 и более поздние версии Версии 12.13.0 и более поздние версии
Только шифрование на стороне клиента версии 1 Версии 12.12.0 и более ранние версии Версии 12.17.0 и более ранние версии Версии 12.12.0 и более ранние версии

Если приложение использует шифрование на стороне клиента с более ранней версией клиентской библиотеки .NET, Java или Python, сначала обновите код до версии, поддерживающей шифрование на стороне клиента версии 2. Затем расшифруйте и повторно зашифруйте данные с помощью функции шифрования на стороне клиента версии 2. При необходимости во время переноса кода вы можете использовать версию клиентской библиотеки, которая поддерживает параллельное шифрование на стороне клиента версии 2, с более ранней версией клиентской библиотеки. Примеры кода см. в разделе Пример. Шифрование и расшифровка BLOB-объекта с помощью функции шифрования на стороне клиента версии 2.

Как работает шифрование на стороне клиента

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

Клиентские библиотеки Хранилища BLOB-объектов используют Azure Key Vault для защиты ключей, применяемых для шифрования на стороне клиента. Дополнительные сведения об Azure Key Vault см. в статье Что такое Azure Key Vault?

Шифрование и расшифровка методом конвертов

Шифрование методом конверта выполняется следующим образом:

  1. Клиентская библиотека Службы хранилища Azure создает ключ шифрования содержимого (CEK), который является симметричным ключом для однократного использования.

  2. Данные пользователя шифруются с помощью этого ключа CEK.

  3. Ключ CEK, в свою очередь, шифруется с помощью ключа шифрования ключа KEK. KEK определяется идентификатором ключа и может быть парой асимметричных ключей или симметричным ключом. Можно управлять ими локально или сохранить их в Azure Key Vault.

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

  4. Затем зашифрованные данные передаются в Хранилище BLOB-объектов Azure. Упакованный ключ с некоторыми дополнительными метаданными шифрования сохраняются как метаданные в BLOB-объекте.

Расшифровка методом конверта выполняется следующим образом:

  1. Клиентская библиотека Службы хранилища Azure предполагает, что пользователь управляет KEK локально или в Azure Key Vault. Пользователь может не знать, какой именно ключ использовался для шифрования. Вместо этого достаточно настроить и использовать сопоставитель ключей, который будет распознавать разные идентификаторы ключей.
  2. Клиентская библиотека скачивает зашифрованные данные вместе с данными шифрования, которые хранятся в Службе хранилища Azure.
  3. Затем упакованный ключ CEK распаковывается (расшифровывается) с помощью KEK. Клиентская библиотека не имеет доступа к KEK во время этого процесса. Она только вызывает алгоритм распаковки Azure Key Vault или другого хранилища ключей.
  4. Клиентская библиотека использует CEK для расшифровки зашифрованных пользовательских данных.

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

Клиентская библиотека Хранилища BLOB-объектов поддерживает полное шифрование BLOB-объектов только при отправке. Что касается загрузок, то поддерживаются как полные, так и диапазонные загрузки.

Во время шифрования клиентская библиотека создает случайный вектор инициализации (IV) размером 16 байт, случайный ключ CEK размером 32 байта и шифрует данные BLOB-объекта методом конверта, используя полученную информацию. Затем упакованный ключ CEK и некоторые дополнительные метаданные шифрования сохраняются как метаданные BLOB-объекта вместе с зашифрованным BLOB-объектом.

Когда клиент скачивает BLOB-объект полностью, упакованный ключ CEK расшифровывается и используется вместе с IV для возврата расшифрованных данных в клиент.

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

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

Предупреждение

Если вы изменяете или загружаете собственные метаданные для BLOB-объекта, убедитесь, что метаданные шифрования сохранены. Если вы отправляете новые метаданные без сохранения метаданных шифрования, то упакованные CEK, IV и другие метаданные будут потеряны и вы не сможете получить содержимое BLOB-объекта. При вызове операции Set Blob Metadata всегда заменяются все метаданные BLOB-объекта.

При чтении или записи в зашифрованном BLOB-объекте используйте команды полной отправки BLOB-объекта, например Put Blob и команды диапазонного либо полного скачивания BLOB-объекта, например Get Blob. Не допускайте записи в зашифрованный BLOB-объект с помощью таких операций протокола, как Put Block, Put Block List, Put Page или Append Block. Вызов этих операций в зашифрованном BLOB-объекте может повредить его и сделать недоступным для чтения.

Пример. Шифрование и расшифровка BLOB-объекта с помощью функции шифрования на стороне клиента версии 2

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

Важно!

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

Чтобы использовать функцию шифрования на стороне клиента из кода .NET, обратитесь к клиентской библиотеке Хранилища BLOB-объектов. Убедитесь, что используется версия 12.13.0 или более поздняя версия. Чтобы перейти с версии 11.x на версию 12.13.0, ознакомьтесь с этим руководством по миграции.

Для интеграции с Azure Key Vault для шифрования на стороне клиента требуются два дополнительных пакета:

  • Пакет Azure.Core, который предоставляет интерфейсы IKeyEncryptionKey и IKeyEncryptionKeyResolver. Клиентская библиотека Хранилища BLOB-объектов для .NET уже определяет эту сборку как зависимость.

  • Пакет Azure.Security.KeyVault.Keys (версия 4.x и более поздние версии) предоставляет клиент REST Key Vault и криптографические клиенты, используемые с функцией шифрования на стороне клиента. Обязательно добавьте в проект ссылку на этот пакет, если используете Azure Key Vault в качестве хранилища ключей.

    Решение Azure Key Vault разработано для главных ключей с большим значением, и ограничения регулирования, связанные с хранилищем ключей, отражают это. Начиная с Azure.Security.KeyVault.Keys версии 4.1.0, интерфейс IKeyEncryptionKeyResolver не поддерживает кэширование ключей. Если кэширование необходимо из-за регулирования, вы можете использовать подход, продемонстрированный в этом примере, чтобы внедрить слой кэширования в экземпляр Azure.Security.KeyVault.Keys.Cryptography.KeyResolver.

Разработчики могут предоставить ключ и (или) сопоставитель ключей. Ключи идентифицируются с помощью идентификатора ключа, который обеспечивает логику для упаковки и распаковки CEK. Сопоставитель ключей используется для сопоставления ключа во время расшифровки. Сопоставитель ключей определяет метод, который возвращает ключ по определенному идентификатору. Этот сопоставитель позволяет пользователям выбирать между несколькими ключами, которые хранятся в разных расположениях.

При шифровании ключ используется всегда, и его отсутствие приводит к возникновению ошибок.

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

Чтобы использовать функцию шифрования на стороне клиента, создайте объект 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(connectionString, 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);

Параметры шифрования можно применять к конструкторам BlobServiceClient, BlobContainerClient или BlobClient, которые принимают объекты BlobClientOptions.

Если объект 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);

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

Повторное шифрование ранее зашифрованных данных с помощью функции шифрования на стороне клиента версии 2

Все данные, которые ранее были зашифрованы с помощью функции шифрования на стороне клиента версии 1, необходимо расшифровать, а затем повторно зашифровать с помощью функции шифрования на стороне клиента версии 2, чтобы уменьшить уязвимость системы безопасности. Для расшифровки нужно скачать данные, а для повторного шифрования — повторно отправить их в Хранилище BLOB-объектов.

Пример проекта, показывающий, как перевести данные с шифрования на стороне клиента версии 1 на версию 2 и как зашифровать данные с помощью функции шифрования на стороне клиента версии 2 в .NET, см. на странице Пример проекта миграции для функции шифрования.

Шифрование на стороне клиента и производительность

Учитывайте, что шифрование результатов анализа данных хранилища отрицательно влияет на производительность. При использовании шифрования на стороне клиента в приложении клиентская библиотека должна в безопасном режиме создать CEK и IV, шифровать само содержимое, взаимодействовать с выбранным хранилищем ключей для шифрования ключей, а также форматировать и отправлять дополнительные метаданные. Эти издержки зависят от объема шифруемых данных. Мы рекомендуем клиентам всегда тестировать свои приложения для повышения производительности во время разработки.

Дальнейшие действия