1

我最近开始探索“Tink”,现在卡在一个特定的问题上,在文档或在线上找不到解决方案。

情况是:我想要两组公钥/私钥对。一个将处于活动状态,另一个将被禁用。

我所做的是生成这样的KeyHandle并将其存储在AWS KMS中:

KeysetHandle pri = KeysetHandle.generateNew(SignatureKeyTemplates.ECDSA_P256);
KeysetHandle pub = privateKeySetHandle.getPublicKeysetHandle();

pri.write(JsonKeysetWriter.withFile(new File("pri_p")),
            new AwsKmsClient().withDefaultCredentials().getAead(keyStoreUrl));
pub.write(JsonKeysetWriter.withFile(new File("pub_p")),
            new AwsKmsClient().withDefaultCredentials().getAead("someUrl"));

//*************** Same code for secondary **************

KeysetHandle pri = KeysetHandle.generateNew(SignatureKeyTemplates.ECDSA_P256);
KeysetHandle pub = privateKeySetHandle.getPublicKeysetHandle();

pri.write(JsonKeysetWriter.withFile(new File("pri_s")),
            new AwsKmsClient().withDefaultCredentials().getAead(keyStoreUrl));
pub.write(JsonKeysetWriter.withFile(new File("pub_s")),
            new AwsKmsClient().withDefaultCredentials().getAead("someUrl"));

我这样做是因为我认为我会生成两对并将它们保存在不同的 json 文件中:

  1. 'pri-p'(主要)
  2. 'pub-p' (主要)
  3. 'pri-s'(次要)
  4. 'pub-s'(次要)

完成此操作后,我编写了一个 API,它将公钥(主密钥和辅助密钥)返回给客户端,响应为:

({
"primaryKeyId": 12345,
"key": [{
    "keyData": {
        "typeUrl": "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey",
        "keyMaterialType": "ASYMMETRIC_PUBLIC",
        "value": "IDJNVUs,csaIQDP9jhF+MERyoZ6Ede/LteBYS0n4zVbYTcuCZCiFBERhyIhAJettefH3BPjFyyZC3m90Pw+m/K8sjiEPS"
    },
    "outputPrefixType": "TINK",
    "keyId": 12345,
    "status": "ENABLED"
}]
},{
"primaryKeyId": 6789,
"key": [{
    "keyData": {
        "typeUrl": "type.googleapis.com/google.crypto.tink.EcdsaPublicKey",
        "keyMaterialType": "ASYMMETRIC_PUBLIC",
        "value": "EgYI7hfsdhfsdm0eeii3m43434334390439TcuCZCiFBERhyIhAJettefH3BPjFyyZC3m90Pw+m/K8sjiEPSXKSMgmWEgr"
    },
    "outputPrefixType": "TINK",
    "keyId": 6789,
    "status": "ENABLED"
}]
})

现在我想将第二个设置为非活动状态,以便没有人使用它,这意味着status: DISABLED使用如下代码:

KeysetHandle secondaryPublicKey = KeysetManager
            .withKeysetHandle(secondaryPublicKey)
            .disable(keySetHandle.getKeysetInfo().getPrimaryKeyId())
            .getKeysetHandle();

但我得到了例外:

java.security.generalsecurityexception: cannot disable the primary key

那时,我意识到我所做的事情是错误的,我不得不再次这样做,以便两个Keys在同一个KeysetHandle中,而我无法像创建 KeysetHandle 时那样做:

KeysetHandle pri = KeysetHandle.generateNew(SignatureKeyTemplates.ECDSA_P256);

它已经被标记为主键,如果我从中检索公钥,那也将是主键。无论我生成多少密钥,都将使用它标记为主要密钥。

还有另一种方式:

  1. 创建多个密钥
  2. 添加键集
  3. 将其中一个标记为主要
  4. 创建KeysetHandle
  5. 写入 AWS Kms

但我不确定该怎么做,或者它是否是正确的方法。

在这方面需要一些帮助,我真的很感激。

4

1 回答 1

0

对的,这是可能的。根据定义,一个 Keyset 可以包含多个键。其中一个是主要的,其余的是活动的。主键可以签名和验证,而主键只能验证。

您可以这样做:

1/ 使用 KeysetManger 生成一个包含两个键的新KeysetHandle

KeysetManager km = KeysetManager.withEmptyKeyset();
// Add a primary key
km.rotate(SignatureKeyTemplates.ECDSA_P256);
// Add a secondary key
km.add(SignatureKeyTemplates.ECDSA_P256);

2/ 从 KeyManager 中检索 KeysetHandle

KeysetHandle kh = km.getKeyHandle()

3/ 加密并将其写入 JSON 文件,就像您在代码中所做的那样。

希望有帮助,泰国人。

于 2019-01-31T07:16:20.557 回答