键和参数对象

<ph type="x-smartling-placeholder">

在实际操作中,Tink 会提供 Key 对象来表示 用于表示 ParameterskeyParameters 对象。 例如,在 Java 中,有 AesGcmKey 对象用于 表示 AES GCM 密钥。

在本部分中,我们将介绍如何在 Java 中设计这些对象,以及如何 互动

Parameters 个对象

请考虑采用广泛使用的 AEAD 加密方案 AES GCM。 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() {...}
}

如本节所述 密钥集、标记加密文、 当某些密钥位于密钥集内时,它们对 ID 有要求。每个 Parameters 对象有一个 hasIdRequirement 方法,用于指定是否将 此 Parameters 对象创建的键是否具有这样的必需 ID。

AesGcmParameters 对象接下来提供 getKeySizeBytes() 方法, getIvSizeBytes()getTagSizeBytes()。这些函数会返回 使用的密钥、使用的 IV 的长度以及生成的标签的长度, (以字节为单位)。尽管 Tink 提供了一些此类函数,但 并不总是允许为每个选择创建 Aead。例如,目前 AES GCM 仅支持 12 个字节的 IV。

AesGcmParameters 对象还会替换之前的 定义的方法(以及 Java 标准方法 equalshashCode) 这被视为一种很好的做法)。

最后,它还提供了用于创建新的 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 方法会返回此键需要具有的 ID。 如果没有要求,则为 null。 (对于密钥,之所以这样要求,是因为 Tink 在某些情况下可能 使用字符串 0x01<id> 为密文或签名添加前缀,请参阅此部分 密文标记)。

这始终与 getParameters().hasIdRequirement() 以及 关键类需要确保这一点。

Key 的实现还需要提供一个 equalsKey 方法, 比较不同的键此类 方法通常很有用:例如,在测试密钥派生时, 旨在确保重复应用该推导可产生 相同的键对象。另外,KMS 可能想要检查其中是否存在任何密钥 提供给不同用户的服务是平等的( 密钥并将其多次上传到同一 KMS)。值得注意的是, 不要替换 Java 方法 equals,因为这需要我们执行以下操作: 替换 hashCode,并且无法在安全的环境中实现 hashCodeequals 兼容,而无需做出未经证明的假设。

接下来,我们需要 getParameters() 方法。这样,用户便可以在 与用于创建键的参数有关的原始信息。

最后,AesGcmKey 具有 getKeyBytes 方法,该方法会返回原始密钥材料。 此类方法对于键类来说非常典型:它们因类型而异, 并提供对底层密钥材料的访问权限。借助这些功能,用户 例如实现由键表示的基元, 或者对密钥进行序列化,以便将其存储在磁盘上,或者通过 。密钥本身负责保护密钥材料 未经授权的访问。例如,SecretBytes 需要访问令牌才能 提供 (请参阅访问权限控制)。

非对称密钥

对于非对称基元,Tink 使用两个 Key 类,一个用于私有,一个 。对于 Parameters,使用与 类(因为只有一个类可用于生成键)。

Tink 还有一个接口 PrivateKey,其中包含额外的 函数 getPublicKey()