Формат провода Тинк

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

сериализация набора ключей

Tink использует протокол Google protobuf для сериализации своих наборов ключей.

  • Сериализованный двоичный набор ключей — это сериализованный прототип Keyset, определенный в файле tink.proto . Свойство KeyData, определяющее значение ключа, представляет собой сериализованный прототип соответствующего типа ключа.
  • Сериализованный в формате JSON набор ключей представляет собой прототип Keyset, сериализованный в формате JSON . Обратите внимание, что значение KeyData по-прежнему является двоичным сериализованным прототипом.
  • Зашифрованный набор ключей — это сериализованный протокол EncryptedKeyset, определенный в файле tink.proto . Он содержит зашифрованный двоичный сериализованный набор ключей и, при необходимости, некоторые незашифрованные метаданные KeysetInfo.

Префикс вывода Tink

Большинство примитивов Tink поддерживают 5-байтовый выходной префикс, состоящий из:

  • Версия в 1 байт: 0x01
  • Подсказка по ключу (4 байта): это идентификатор используемого ключа.

Некоторые устаревшие ключи также могут поддерживать байт версии 0x00 .

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

АЭАД

В целом, Tink форматирует зашифрованные данные AEAD следующим образом:

prefix || IV || ciphertext || tag

Если иное не указано в соответствующем RFC, prefix либо пуст, либо представляет собой 5-байтовый префикс вывода Tink.

AES-CTR-HMAC

Для алгоритма AES-CTR-HMAC компания Tink вычисляет MAC с соответствующими данными (AD) следующим образом:

AD || IV || ciphertext || bitlen(AD)

где bitlen(AD) — длина AD в битах, представленная в виде 64-битного беззнакового целого числа в порядке байтов big-endian. Эта схема HMAC соответствует проекту AES-CBC-HMAC от Mcgrew .

Детерминированная АЭАД

Tink реализует RFC 5297 для AES-SIV, помещая синтетический вектор инициализации (SIV) в начало зашифрованного текста. Примитив может добавлять 5-байтовый префикс выходных данных Tink.

В то время как RFC 5297 поддерживает список связанных данных, Tink поддерживает только один связанный набор данных, что соответствует списку с одним элементом в RFC 5297. Пустой связанный набор данных — это список с одним пустым элементом, а не пустой список.

Трансляция AEAD

См. AES-CTR HMAC и AES-GCM-HKDF .

Шифрование конверта

Шифрование с использованием конверта (Envelope encryption) шифрует данные с помощью ключа шифрования данных DEK , используя примитивы AEAD из библиотеки Tink. Шифрование работает следующим образом:

  • Создается новый DEK с использованием заданного шаблона ключа (или параметров ключа).
  • DEK сериализуется в байтовую строку. Формат сериализации соответствует сериализации протокола буфера протокола для типа ключа proto. Например, это сериализованное сообщение протокола буфера AesGcmKey , определенное в файле aes_gcm.proto для DEK типа ключа AES GCM. См. раздел «Сериализация протокола буфера» для получения информации о том, как сериализовать протокол буфера протокола.
  • Сериализованный DEK шифруется внешним поставщиком (например, GCP) и преобразуется в encrypted DEK .
  • DEK используется для шифрования открытого текста вместе с соответствующими данными в ciphertext . Таким образом, ciphertext имеет точно такой же формат, как и примитив AEAD, соответствующий DEK .

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

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length составляет 4 байта, при этом длина encrypted DEK хранится в виде 32-битного целого числа в формате big-endian.

MAC

Tink следует соответствующим RFC. Примитивы могут добавлять 5-байтовый префикс выходных данных Tink к тегу.

набор PRF

Tink следует соответствующим RFC. Обратите внимание, что для PRF Set тип ключа отличается от типа ключа MAC того же алгоритма тем, что не включает длину выходных данных. Ключи PRF Set никогда не добавляют префикс выходных данных Tink. Это гарантирует, что выходные данные действительно являются PRF.

Гибридное шифрование

Общий формат передачи данных для гибридного шифрования Tink выглядит следующим образом:

prefix || encapsulated_key || encrypted_data

prefix либо пуст, либо представляет собой 5-байтовый префикс вывода Tink. Каждый тип ключа содержит информацию о том, сколько байтов нужно разобрать и как это сделать, из encapsulated_key .

HPKE (гибридное шифрование с открытым ключом)

Tink соответствует стандарту HPKE, определенному в RFC 9180. Набор шифров HPKE включает следующие три примитива.

  • Ключевой механизм инкапсуляции (KEM)
  • Функция ключевого вывода (KDF)
  • Аутентифицированное шифрование с ассоциированными данными (AEAD)

Стандарт HPKE не определяет общий формат передачи данных в RFC 9180, Раздел 10. В реализации HPKE от Tink используются следующие значения encapsulated_key и encrypted_data .

  • encapsulated_key
    • Серийный открытый ключ отправителя
    • В RFC 9180, раздел 4.1, обозначен как enc
    • Формат определяется конкретным используемым модулем HPKE KEM.
  • encrypted_data
    • Зашифрованный текст и метка (т.е., ciphertext || tag без вектора инициализации)
    • В RFC 9180, Раздел 4, обозначен как ct
    • Формат определяется конкретной используемой версией HPKE AEAD.
X25519 KEM на основе алгоритма Диффи-Хеллмана

Для DHKEM-сообщений X25519 значение enc представляет собой 32-байтовый открытый ключ Диффи-Хеллмана отправителя.

ECIES-AEAD-HKDF

В реализации ECIES-AEAD-HKDF от Tink, encapsulated_key является результатом работы механизма инкапсуляции ключей (KEM), а encrypted_data — результатом работы механизма инкапсуляции данных (DEM).

КЕМ

В зависимости от типа ключа, Tink использует сжатые и несжатые точки эллиптических кривых в соответствии со стандартами кодирования RFC 8422 / ANSI.X9-62.2005 . Для несжатых точек за байтом 0x04 следуют координаты x и y в виде целых чисел фиксированного размера. Для сжатых координат используются байт 0x02 или 0x03 и координата x в виде целого числа фиксированного размера. Для X25519 используется определение RFC 7748 (координата x в виде целого числа фиксированного размера).

ДЕМ

Для encrypted_data Tink использует тот же формат, что и AEAD. Это включает в себя указание вектора инициализации (IV).

Вывод ключей

Сначала вычисляется координата x_ss общей точки. Затем устанавливается ключ для AEAD следующим образом:

HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)

где encapsulated_key — это полный вывод KEM в байтах.

Цифровые подписи

Tink следует соответствующим RFC. Примитивы могут добавлять 5-байтовый префикс выходных данных Tink к генерируемому тегу.

ECDSA

В зависимости от поля EcdsaSignatureEncoding в ключе, формат подписи ECDSA может быть либо IEEE P1363 , либо ASN.1 DER .

Формат подписи IEEE P1363r || s , где r и s дополняются нулями и имеют тот же размер в байтах, что и порядок кривой. Например, для кривой NIST P-256 r и s дополняются нулями до 32 байт.

Подпись DER кодируется с использованием ASN.1 :

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

В частности, кодировка выглядит следующим образом:

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink следует передовым методам проверки подписей, принимая только подписи ECDSA в кодировке DER (альтернативные подписи в кодировке BER недействительны).

Это помогает предотвратить атаки, связанные с изменением подписи, которые часто затрагивают криптовалютные системы .

Внешние значения предварительного хеширования Mu ML-DSA

Примитив Prehash преобразует сообщение в значение прехеша , которое затем подписывается примитивом SignPrehash. Для ML-DSA в режиме External Mu , как описано в RFC 9881 , значение прехеша составляет 69 байт и имеет следующую структуру:

0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
  • mu — это представитель сообщения ML-DSA, вычисляемый как SHAKE256(tr || 0x00 || 0x00 || message, 64) , где tr — 64-байтовый хеш открытого ключа, первый 0x00 — это разделитель доменов FIPS 204 для чистого ML-DSA, а второй 0x00 — длина (пустой) контекстной строки. Поскольку tr вычисляется на основе открытого ключа, mu криптографически связан с этим ключом — хотя для проверки связи требуется исходное сообщение.
  • 5-байтовый префикс — это фрейминг Tink, а не часть mu . Он связывает значение прехеша с одним конкретным ключом, так что SignPrehash знает, каким ключом подписывать, и может отклонить значение прехеша, для которого у него нет ключа. Префикс представляет собой обычные метаданные и ничего не связывает криптографически: любой может его переписать.

Процесс подписи отклоняет любые входные данные, размер которых не превышает 69 байт, которые не начинаются с 0xff , или идентификатор ключа которых не совпадает с включенным ключом в его наборе ключей.