Поделиться через


Шифрование на стороне клиента для 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 и более ранние версии

Примечание.

Шифрование на стороне клиента версии 2.1 доступно в пакете SDK java для версий 12.27.0 и более поздних версий. Эта версия позволяет настроить длину региона для проверки подлинности шифрования с 16 байт до 1 ГиБ. Дополнительные сведения см. в примере Java: шифрование и расшифровка большого двоичного объекта с помощью клиентского шифрования версии 2.

Если приложение использует шифрование на стороне клиента с более ранней версией клиентской библиотеки .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-объектов только при отправке. Что касается загрузок, то поддерживаются как полные, так и диапазонные загрузки. Шифрование на стороне клиента версии 2 блокирует данные в 4 буферированных блоках шифрования, прошедших проверку подлинности, которые можно преобразовать только целиком. Чтобы настроить размер блока, убедитесь, что используется последняя версия пакета SDK, поддерживающая шифрование на стороне клиента версии 2.1. Длина региона настраивается от 16 байт до 1 ГиБ.

Во время шифрования клиентская библиотека создает случайный вектор инициализации (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
(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);

Параметры шифрования можно применять к конструкторам 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, шифровать само содержимое, взаимодействовать с выбранным хранилищем ключей для шифрования ключей, а также форматировать и отправлять дополнительные метаданные. Эти издержки зависят от объема шифруемых данных. Мы рекомендуем клиентам всегда тестировать свои приложения для повышения производительности во время разработки.

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