Важно, чтобы Tink вел себя одинаково на всех языках программирования. Это непростая концепция, но самое главное:
Для обеспечения согласованности в Tink используются межъязыковые тесты, которые можно найти в межъязыковом репозитории GitHub. Эти тесты проверяют согласованность и совместимость разных языков.
Однако определить, что такое согласованность, не так просто, как кажется. Поэтому на этой странице мы приводим рабочее определение. В основном Tink обеспечивает два типа согласованности:
- Согласованность оценки. Если для набора ключей 1 примитив успешно создается на двух языках, то он ведет себя одинаково.
- Согласованность создания. Примитив успешно создается на языке, если этот язык поддерживает все типы ключей в наборе. Подробнее о поддерживаемых типах ключей…
Контекст
Tink предоставляет следующие API:
Управление наборами ключей. Tink предоставляет API для добавления новых ключей в набор, удаления ключей из набора и изменения первичного ключа в наборе.
Сериализация набора ключей. Tink предоставляет API для сериализации набора ключей в последовательность байтов и, наоборот, для синтаксического анализа набора ключей из последовательности байтов.
Создание примитивов. Tink предоставляет API для создания интерфейса примитива из набора ключей. Например, чтобы создать объект
Aeadиз набора ключей в Java, пользователь вызываетkeysetHandle.getPrimitive(config, Aead.class).Использование примитива. Интерфейс, созданный на этапе создания примитива, предоставляет API для выполнения криптографических операций.
В отношении этих API важно задать два вопроса:
Создание. Можно ли создать примитив на основе сериализованного набора ключей на определенном языке?
Оценка. Если примитив можно создать на каком-либо языке из заданного набора ключей, как ведет себя объект примитива?
Важно отметить, что Tink не обеспечивает согласованность при синтаксическом анализе набора ключей. Например, возможно, что Tink C++
- успешно анализирует наборы ключей, содержащие ключи CHACHA20-POLY1305, несмотря на то, что операции CHACHA20-POLY1305 AEAD не реализованы в Tink;
- успешно анализирует наборы ключей с ключами длиной 1 байт, которые не будут работать во всех криптографических операциях.
В промежуточных версиях это поведение может измениться.
Согласованность оценок
Согласованность оценки важнее, чем согласованность процесса создания: если AEAD на Java не может расшифровать шифрование AEAD на C++, у пользователей возникнет серьезная проблема.
В целом Tink стремится быть последовательным в очевидном отношении к примитивам. Например, если двоичный файл C++ вычисляет подпись с помощью public_key_sign->Sign(data), соответствующий вызов проверки Java publicKeyVerify.verify(signature, data) должен быть успешным.
Однако даже в этом случае есть некоторые нюансы. Например, тип возвращаемого значения aead.Encrypt в Java – byte[].
Согласно спецификации языка Java (JLS) §10.7, длина массива имеет тип int, который согласно §JLS 4.2.1 может иметь максимальное значение 2147483647. Поэтому шифрование массива длиной 2147483647 в Java завершается ошибкой: шифрование требует дополнительных ресурсов, а значит, выходные данные будут слишком длинными. Однако в других языках шифрование таких входных данных разрешено.
Таким образом, Tink обеспечивает согласованность оценки: для заданного набора ключей, если создание примитива успешно выполняется на двух языках, они ведут себя одинаково.
Исключение составляют некоторые операции, которые могут завершиться ошибкой в исключительных обстоятельствах.
Регулярность публикаций
Создание примитивов не всегда успешно для всех наборов ключей. Например, Tink не позволяет пользователям создавать AesSivKey, если длина материала ключа составляет 128 бит.
Тем не менее Tink обеспечивает согласованность следующим образом: если два языка поддерживают тип ключа, набор ключей, для которых может быть создан примитив, совпадает. Если язык не поддерживает тип ключа, то примитивный объект создать нельзя.
Согласованность создания менее важна, чем согласованность оценки, и из этого правила больше исключений, чем для согласованности оценки. Эти ограничения описаны в списке поддерживаемых типов ключей. Например, для типа ключа ECIES Tink предлагает выбрать эллиптическую кривую для согласования ключей, но Java не поддерживает X25519. Поэтому создать ключ с помощью X25519 в Java не удастся.
-
В этом документе мы используем термин
Keysetдля обозначения объекта, который в большинстве языков называетсяKeysetHandle. ↩