Последовательность

Важно, чтобы Tink вел себя «одинаково» на всех языках программирования. Эта концепция не является простой, но наиболее важной:

Чтобы обеспечить согласованность, Tink использует кросс-языковые тесты, которые можно найти в кросс-языковом репозитории GitHub . Эти тесты проверяют согласованность и совместимость разных языков.

Однако определить согласованность не так просто, как можно было бы ожидать. Следовательно, на этой странице представлено наше рабочее определение. По сути, Tink обеспечивает два типа согласованности:

Контекст

На высоком уровне Tink предоставляет следующие API:

  • Манипулирование набором ключей: Tink предоставляет API для добавления новых ключей в набор ключей, удаления ключей из набора ключей и изменения первичного ключа в наборе ключей.

  • Сериализация набора ключей: Tink предоставляет API для сериализации набора ключей в последовательность байтов и, наоборот, анализа набора ключей из последовательности байтов.

  • Создание примитивов: Tink предоставляет API для создания интерфейса для примитива из набора ключей. Например, чтобы создать объект Aead из набора ключей в Java, пользователь вызывает keysetHandle.getPrimitive(Aead.class, config) .

  • Примитивное использование: интерфейс, созданный на этапе создания примитива, предоставляет API для выполнения криптографических операций.

Есть два важных вопроса, которые следует задать об этих API:

  • Создание: возможно ли для данного сериализованного набора ключей, языка и примитива создать примитив из этого набора ключей на языке?

  • Оценка: если примитив может быть создан на каком-либо языке из заданного набора ключей, как ведет себя примитивный объект?

Важно отметить, что Tink не обеспечивает согласованность при анализе набора ключей. Например, возможно, что Tink C++

  • успешно анализирует наборы ключей, содержащие ключи CHACHA20-POLY1305, хотя операции AEAD CHACHA20-POLY1305 не реализованы в Tink;
  • успешно анализирует наборы ключей с ключами длиной 1 байт, что приводит к сбою во всех криптографических операциях.

Это поведение может измениться в минорных версиях.

Последовательность оценки

Согласованность оценки более важна, чем любая согласованность в процессе создания: если AEAD в Java не может расшифровать шифрование AEAD в C++, у пользователей возникает серьезная проблема.

В целом, Tink стремится быть последовательным в отношении примитивов. Например, если двоичный файл C++ вычисляет подпись с помощью public_key_sign->Sign(data) , ожидается, что соответствующий вызов проверки Java publicKeyVerify.verify(signature, data) будет успешным.

Однако и здесь есть некоторые предостережения. Например, тип возвращаемого значения aead.Encrypt в Java — byte[] . Согласно §10.7 спецификации языка Java (JLS), длина массива имеет тип int , который согласно §JLS 4.2.1 может составлять максимум 2147483647. Следовательно, шифрование массива длиной 2147483647 в Java не выполняется: шифрование имеет некоторые накладные расходы, а это означает, что вывод будет слишком длинным. Тем не менее, в других языках шифрование таких входных данных допускается.

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

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

Последовательность создания

Создание примитивов не всегда удается для всех наборов ключей. Например, Tink не позволяет пользователям создавать AesSivKey, если длина материала ключа составляет 128 бит.

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

Согласованность создания менее важна, чем согласованность оценки, и из этого правила больше исключений, чем из согласованности оценки. Эти ограничения описаны в нашем списке поддерживаемых типов ключей . Например, для типа ключа ECIES Tink предлагает выбор, какую эллиптическую кривую использовать для согласования ключей, но Java не поддерживает X25519. Следовательно, создание ключа с использованием X25519 в Java не удается.


  1. В этом документе мы используем термин Keyset для обозначения объекта KeysetHandle на большинстве языков.