键和参数对象

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

在实际操作中,Tink 会提供 Key 对象来表示 用于表示 Parameters 的 key 和 Parameters 对象。 例如,在 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 标准方法 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 方法会返回此键需要具有的 ID。 如果没有要求,则为 null。 (对于密钥,之所以这样要求,是因为 Tink 在某些情况下可能 使用字符串 0x01<id> 为密文或签名添加前缀,请参阅此部分 密文标记)。

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

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

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

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

非对称密钥

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

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