На практике Tink предоставляет объекты Key
для представления ключей и объекты Parameters
для представления Parameters
. Например, в Java у нас есть объекты AesGcmKey
для представления ключей AES GCM.
В этом разделе мы объясним, как эти объекты спроектированы в Java и как они взаимодействуют.
Объекты Parameters
Рассмотрим AES GCM, широко используемую схему шифрования AEAD. Tink предоставляет объекту AesGcmParameters
необходимую информацию для создания AesGcmKey
, что мы объясним позже. Иерархия параметров в Java выглядит следующим образом:
public abstract class Parameters {
public abstract boolean hasIdRequirement();
}
public abstract class AeadParameters extends Parameters {}
public final class AesGcmParameters extends AeadParameters {
/**
* The Variant specified how ciphertexts are [tagged](/tink/design/keysets#tagging_ciphertexts).
*/
public static final class Variant {...}
/** A helper object to create new AesGcmParameters. */
public static final class Builder {...}
public int getKeySizeBytes() {...}
public int getIvSizeBytes() {...}
public int getTagSizeBytes() {...}
public Variant getVariant() {...}
public OutputPrefixType getOutputPrefixType() {...}
public boolean equals(Object object) {...}
public int hashCode() {...}
}
Как объясняется в разделе «Наборы ключей, маркировка зашифрованных текстов» , для некоторых ключей требуется идентификатор, когда они находятся в наборе ключей. Каждый объект Parameters
имеет метод hasIdRequirement
, который определяет, будет ли ключ, созданный этим объектом Parameters
, иметь такой требуемый идентификатор или нет.
Далее объект AesGcmParameters
предоставляет методы getKeySizeBytes()
, getIvSizeBytes()
и getTagSizeBytes()
. Они возвращают длину используемого ключа, длину используемого IV и длину созданного тега в байтах. Хотя Tink предоставляет некоторые из этих функций для полноты, он не всегда позволяет создавать Aead
для каждого выбора. Например, в настоящее время для AES GCM поддерживаются только 12-байтовые IV.
Объект AesGcmParameters
также предоставляет переопределения для ранее определенных методов (а также стандартных методов Java, equals
и hashCode
, что считается хорошей практикой).
Наконец, он предоставляет статические методы для создания новых объектов AeadParameters
. Они проверяют входные данные, то есть проверяют, что размер равен одному из 16, 24 или 32.
Ключевые объекты
У Tink также есть ключевая иерархия. Если рассматривать наш пример AES GCM, то это выглядит так:
public abstract class Key {
public abstract Parameters getParameters();
public abstract @Nullable Integer getIdRequirementOrNull();
public abstract boolean equalsKey(Key other);
}
public abstract class AeadKey extends Key {
public abstract AeadParameters getParameters();
public abstract Bytes getOutputPrefix();
}
public final class AesGcmKey implements AeadKey {
public SecretBytes getKeyBytes();
public abstract Bytes getOutputPrefix();
public AesGcmParameters getParameters();
public @Nullable Integer getIdRequirementOrNull();
public boolean equalsKey(Key object);
}
Метод getIdRequirementOrNull
возвращает идентификатор, который должен иметь этот ключ, или null
если это не требуется. (Такое требование к ключу связано с тем, что Tink в некоторых случаях ставит перед зашифрованными текстами или подписями префикс строки 0x01<id>
, см. раздел о разметке зашифрованного текста ).
Это всегда будет соответствовать результату getParameters().hasIdRequirement()
и разработчики новых ключевых классов должны это гарантировать.
Реализации Key
также должны предоставлять метод equalsKey
для сравнения различных ключей. Такой метод часто бывает полезен: например, при тестировании вывода ключа нужно убедиться, что повторное применение вывода дает один и тот же ключевой объект. Кроме того, KMS может захотеть проверить, равны ли какие-либо ключи, которые он предоставляет разным пользователям (что иногда случается, если пользователи используют общие ключи и загружают их в один и тот же KMS несколько раз). Примечательно, что мы не переопределяем Java-метод equals
, поскольку для этого нам потребуется переопределить hashCode
, и не существует способа реализовать hashCode
безопасным способом, совместимым с equals
, без необоснованных предположений.
Далее нам нужен метод getParameters()
. Это позволяет пользователям получить исходную информацию о параметрах, использованных для создания ключа.
Наконец, у AesGcmKey
есть метод getKeyBytes
, который возвращает исходный материал ключа. Такие методы очень типичны для классов ключей: они специфичны для типа и обеспечивают доступ к базовому ключевому материалу. Используя их, пользователи могут, в принципе, реализовать примитив, представленный ключом, или сериализовать ключ, чтобы сохранить его на диске или отправить по сети. Сам ключ отвечает за защиту материала ключа от несанкционированного доступа. Например, SecretBytes
требует токен доступа для фактического предоставления материала (см. Контроль доступа ).
Асимметричные клавиши
Для асимметричных примитивов Tink использует два класса Key: один для частных и один для открытых ключей. Для параметров удобнее использовать один и тот же класс (поскольку для генерации ключей можно использовать только один класс).
У Tink также есть интерфейс PrivateKey
с дополнительной функцией getPublicKey()
.