Наборы ключей

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

Наборы ключей — это основной способ доступа пользователей к ключам (через класс KeysetHandle ). Это гарантирует, что у каждого пользователя будет код для одновременной обработки нескольких ключей. Для большинства пользователей криптографии обработка нескольких ключей является необходимостью : должна быть возможность менять ключи (например, могут произойти утечки старых ключей), и почти никогда не существует атомарного «переключения на следующий ключ», который можно было бы применить. на машины выполняется код и все зашифрованные тексты, глобально и в одно мгновение. Следовательно, пользователю необходимо написать код, который будет работать при переходе от одной клавиши к другой.

Пример: АЕАД

Рассмотрим набор ключей AEAD, который содержит несколько ключей для примитива AEAD. Как объяснялось ранее, каждый ключ однозначно определяет две функции: \(\mathrm{Enc}\) и \(\mathrm{Dec}\). Набор ключей теперь также определяет две новые функции: \(\mathrm{Enc}\) и \(\mathrm{Dec}\) — \(\mathrm{Enc}\) просто соответствует функции \(\mathrm{Enc}\) первичного ключа набора ключей, а функция \(\mathrm{Dec}\) пытается расшифровать со всеми ключами, проходя их в некотором порядке (см. ниже , как Tink улучшает производительность этого процесса).

Интересно отметить, что наборы ключей — это полные ключи : они представляют собой полное описание используемых функций \(\mathrm{Enc}\) и\(\mathrm{Dec}\) . Это означает, что пользователи могут написать класс, который принимает в качестве входных данных KeysetHandle , выражая идею о том, что классу необходимо полное описание объектов \(\mathrm{Enc}\) и \(\mathrm{Dec}\) для правильной работы . Это позволяет пользователю писать API, которые сообщают следующее: чтобы использовать этот класс, вам необходимо предоставить мне описание криптографического примитива.

Ключевое вращение

Рассмотрим пользователя Tink, который пишет программу, которая сначала получает набор ключей от KMS, затем создает объект AEAD из этого набора ключей и, наконец, использует этот объект для шифрования и дешифрования зашифрованных текстов.

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

Однако при реализации такой ротации ключей следует быть несколько осторожным: во-первых, KMS должен добавить новый ключ в набор ключей (но еще не устанавливать его в качестве основного). Затем новый набор ключей необходимо распространить на все двоичные файлы, чтобы каждый двоичный файл, использующий этот набор ключей, имел самый новый ключ в наборе ключей. Только после этого новый ключ следует сделать первичным, а полученный набор ключей снова распространить на все двоичные файлы, использующие этот набор ключей.

Ключевые идентификаторы в зашифрованных текстах

Рассмотрим еще раз пример набора ключей AEAD. Если все сделано наивно, расшифровка зашифрованного текста потребует, чтобы Tink попытался расшифровать все ключи в наборе ключей, поскольку невозможно узнать, какой ключ использовался для шифрования набора ключей. Это может привести к большим потерям производительности.

По этой причине Tink позволяет добавлять к зашифрованным текстам префикс 5-байтовой строки, полученной из идентификатора. Следуя вышеизложенной философии «Полных ключей», этот префикс является частью ключа , и все зашифрованные тексты, когда-либо полученные с помощью этого ключа, должны иметь этот префикс. Когда пользователи создают ключи, они могут выбрать, должен ли ключ использовать такой префикс или следует использовать формат зашифрованного текста без него.

Когда ключ находится в наборе ключей, Tink вычисляет этот тег на основе идентификатора, который ключ имеет в наборе ключей. Тот факт, что идентификаторы уникальны 2 в наборе ключей, подразумевает, что теги уникальны. Следовательно, если используются только помеченные ключи, производительность не снижается по сравнению с расшифровкой с помощью одного ключа: Tink нужно использовать только один из ключей при расшифровке.

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


  1. Некоторые части Tink по-прежнему рассматривают наборы ключей как набор. Однако это следует изменить. Причина в том, что порядок в целом важен: например, рассмотрим типичный жизненный цикл ротации ключей с помощью Aead. Сначала в набор ключей добавляется новый ключ. Этот ключ еще не стал основным, но активным. Этот новый набор ключей распространяется на все двоичные файлы. Как только все двоичные файлы узнают новый ключ, ключ становится первичным (только на этом этапе использование этого ключа безопасно). На этом втором этапе при ротации ключей необходимо знать последний добавленный ключ.

  2. Для совместимости с внутренней библиотекой Google Tink позволяет использовать наборы ключей, в которых идентификаторы повторяются. В будущем эта поддержка будет прекращена.