Наследование подключей и аутентификационное шифрование

Большинство ключей в кольце ключей содержат алгоритмическую информацию, содержащую “шифрование в режиме CBC + HMAC валидацию” или “GCM шифрование + валидацию”. В данных случаях мы ссылаемся на мастер ключи (или KM) для этого ключа и выполняем функции деривации ключей, чтобы наследовать ключи, которые будут использоваться для криптографических операций.

Примечание

Ключи являются абстрактными, и пользовательская реализация может работать по-другому. Если ключ как-то по-иному реализует IAuthenticatedEncryptor, а не использует встроенные фабрики, то мы не сможем использовать механизм, описанный в этой статье.

Дополнительные аутентификационные данные и наследование подключей

Интерфейс IAuthenticatedEncryptor служит базовым интерфейсом для всех операций по аутентификационному шифрованию. Его метод Encrypt принимает два параметра: простой текст и additionalAuthenticatedData (AAD). Простой текст содержит вызов IDataProtector.Protect, а AAD генерируется системой и содержит три компонента:

  1. 32-битный заголовок 09 F0 C9 F0, который определяет версию системы защиты данных.
  2. 128-битный id ключа.
  3. Строку, сформированную из цепочки purpose, создавшую IDataProtector, который выполняет эту операцию.

Поскольку AAD является уникальным, мы можем наследовать его для создания новых ключей из KM вместо использования самого KM во всех криптографических операциях. Для каждого вызова IAuthenticatedEncryptor.Encrypt мы видим следующий процесс наследования ключей:

( KE, KH ) = SP800_108_CTR_HMACSHA512(KM, AAD, contextHeader || keyModifier)

Здесь мы вызываем NIST SP800-108 KDF (см. NIST SP800-108, раздел 5.1) со следующими параметрами:

  • Key derivation key (KDK) = KM
  • PRF = HMACSHA512
  • label = additionalAuthenticatedData
  • context = contextHeader || keyModifier

Контекстный заголовок является “отпечатком пальца” алгоритмов, для которых мы наследуем KE и KH. Модификатор ключа - это 128-битная строка, случайно сгенерированная для каждого вызова Encrypt, которая гарантирует, что KE и KH являются уникальными для этой конкретной операции аутентификационного шифрования, даже если все другие входящие данные для этого KDF являются постоянными.

Для шифрования в режиме CBC + HMAC валидации | KE | - это длина симметричного блочного ключа шифрования, а | KH | - это размер HMAC. Для GCM шифрования + валидации | KH | = 0.

Шифрование в режиме CBC + HMAC валидация

После генерации KE мы генерируем случайный вектор инициализации и запускаем алгоритм симметричного блочного шифрования, чтобы зашифровать текст. Затем вектор инициализации и зашифрованный текст пропускаются через HMAC, инициализированный с помощью KH, чтобы создать MAC. Это процесс и возвращаемое значение представлены на изображении ниже.

CBC-mode process and return

output:= keyModifier || iv || Ecbc (KE,iv,data) || HMAC(KH, iv || Ecbc (KE,iv,data))

Примечание

Реализация IDataProtector.Protect вставляет заголовок и id ключа, прежде чем возвращает данные вызывающему элементу. Поскольку заголовок и id являются частью AAD и поскольку идентификатор ключа считается входными данными для KDF, каждый байт возвращаемых финальных данных аутентифицируется MAC.

Шифрование в режиме Galois/Counter + валидация

После генерации KE мы генерируем случайный 96-битный экземпляр и запускаем алгоритм симметричного блочного шифрования, чтобы зашифровать простой текст и создать 128-битный тег аутентификации.

GCM-mode process and return

output := keyModifier || nounce || Egcm (KE,nounce,data) || authTag

Примечание

Хотя GCM поддерживает концепцию AAD, мы отдаем AAD только оригинальному KDF, разрешая передать пустую строку GCM для его параметра AAD. Для этого есть две причины. Во-первых, чтобы поддержать гибкость, мы не используем KM напрямую в качестве ключа шифрования. Кроме того, GCM предъявляет очень строгие требования к уникальности своих входных данных. GCM шифрование никогда не вызывается для двух или более отдельных наборов входных данных с одно и той же парой, и оно не должно превышать 232. Если мы закрепим KE, то не сможем выполнять больше чем 232 операций по шифрованию, прежде чем не устраним лимит 2-32. Это может быть очень большое число операций, но сервера с высоким трафиком могут пропускать 4 миллиарда запросов за день, и у этих ключей может быть нормальный жизненный цикл. Для простоты мы распределяем KDF код между CBC и GCM операциями, и поскольку AAD уже работает с KDF, нам не нужно отправлять его GCM.

Поделись хорошей новостью с друзьями!
Следи за новостями!