Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Большинство ключей в кольце ключей будут содержать некоторую форму энтропии и будут иметь алгоритмическую информацию о том, что "шифрование в режиме CBC + проверка HMAC" или "шифрование GCM + проверка". В этих случаях мы ссылаемся на внедренную энтропию как основной материал ключа (или KM) для этого ключа, и мы выполняем функцию создания ключей для получения ключей, которые будут использоваться для фактических криптографических операций.
Замечание
Ключи абстрактны, а пользовательская реализация может не вести себя так, как показано ниже. Если ключ предоставляет собственную реализацию IAuthenticatedEncryptor, вместо использования одной из встроенных фабрик, то механизм, описанный в этом разделе, больше не применяется.
Дополнительные аутентифицированные данные и вывод подчинённого ключа
Интерфейс IAuthenticatedEncryptor служит основным интерфейсом для всех операций шифрования, прошедших проверку подлинности. Его Encrypt метод принимает два буфера: открытый текст и дополнительно аутентифицированные данные (AAD). Поток содержимого с открытым текстом не изменил вызов IDataProtector.Protect, но AAD создается системой и состоит из трех компонентов:
32-разрядный волшебный заголовок 09 F0 C9 F0, определяющий эту версию системы защиты данных.
Идентификатор 128-разрядного ключа.
Строка переменной длины, сформированная из цепочки предназначений, создавшей
IDataProtector, который выполняет эту операцию.
Так как AAD является уникальным для кортежа всех трех компонентов, мы можем использовать его для получения новых ключей от KM, а не использования KM в всех наших криптографических операциях. Для каждого вызова IAuthenticatedEncryptor.Encryptпроисходит следующий процесс получения ключа:
( K_E, K_H ) = SP800_108_CTR_HMACSHA512(K_M, AAD, contextHeader || keyModifier)
Здесь мы вызываем NIST SP800-108 KDF в режиме счетчика (см. NIST SP800-108, sec. 5.1) со следующими параметрами:
Ключ производных ключей (KDK) =
K_MPRF = HMACSHA512
label = дополнительныеАутентифицированныеДанные
context = contextHeader || keyModifier
Заголовок контекста имеет переменную длину и, по сути, служит отпечатком алгоритмов, для которых мы наследуем K_E и K_H. Модификатор ключа — это 128-разрядная строка, созданная случайным образом для каждого вызова Encrypt и служит для обеспечения подавляющей вероятности того, что KE и KH являются уникальными для этой конкретной операции шифрования проверки подлинности, даже если все остальные входные данные KDF являются константой.
Для операций шифрования в режиме CBC и проверки с помощью HMAC, | K_E | обозначает длину ключа симметричного блочного шифра, а | K_H | обозначает размер дайджеста для процедуры HMAC. Для операций шифрования и проверки GCM. | K_H | = 0
Шифрование в режиме CBC + проверка HMAC
После того как K_E сгенерирован с помощью приведенного выше механизма, мы генерируем вектор случайной инициализации и запускаем алгоритм симметричного блочного шифра для зашифровки открытого текста. Затем вектор инициализации и зашифрованный текст пропускаются через подпрограмму HMAC, инициализированную ключом K_H, для создания MAC. Этот процесс и возвращаемое значение представлены графически ниже.
output:= keyModifier || iv || E_cbc (K_E,iv,data) || HMAC(K_H, iv || E_cbc (K_E,iv,data))
Замечание
Реализация IDataProtector.Protect добавит волшебный заголовок и идентификатор ключа к выходным данным перед возвратом вызывающему объекту. Так как магический заголовок и идентификатор ключа являются неявной частью AAD, и поскольку модификатор ключа предоставляется в качестве ввода в KDF, это означает, что каждый байт конечного возвращаемого полезного груза проверяется на подлинность с использованием MAC.
Шифрование в режиме Galois/Counter и проверка
Как только K_E будет создан с помощью приведенного выше механизма, мы создадим случайный 96-битный произвольный номер и запускаем алгоритм симметричного блочного шифра, чтобы зашифровать открытый текст и создать 128-битный тег проверки подлинности.
output := keyModifier || nonce || E_gcm (K_E,nonce,data) || authTag
Замечание
Несмотря на то, что GCM изначально поддерживает концепцию AAD, мы по-прежнему передаем AAD только исходному KDF и решаем передать пустую строку в GCM в качестве его параметра AAD. Причина этого двойственная. Во-первых, для поддержки гибкости мы никогда не хотим использовать K_M непосредственно в качестве ключа шифрования. Кроме того, GCM накладывает очень строгие требования к уникальности для входных данных. Вероятность того, что подпрограмма шифрования GCM когда-либо вызывается на двух или более разных наборах входных данных с той же парой (ключ, nonce) не должно превышать 2^-32. Если мы зафиксируем K_E, мы не можем выполнять более 2^32 операций шифрования, прежде чем превысим предел в 2^-32. Это может показаться очень большим количеством операций, но веб-сервер с высоким трафиком может обработать 4 миллиарда запросов всего за несколько дней, что вполне укладывается в нормальный срок действия этих ключей. Чтобы соблюдать предел вероятности 2^-32, мы продолжаем использовать 128-разрядный модификатор ключа и 96-разрядный nonce, что существенно увеличивает количество операций, доступных для любого данного K_M. Для простоты проектирования мы разделяем путь кода KDF между операциями CBC и GCM, и так как AAD уже рассматривается в KDF, нет необходимости пересылать его в подпрограмму GCM.
ASP.NET Core