Несколько пар закрытый/открытый ключ в Tink

Недавно я начал изучать "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"
}]
})

Теперь я хотел сделать вторичный неактивным, чтобы его никто не использовал, что означает статус: ОТКЛЮЧЕНО, используя код, как показано ниже:

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

Но я не уверен, как это сделать, или это правильный путь.

Нужна помощь в этом, буду очень признателен.


person Muhammad Umer    schedule 29.01.2019    source источник


Ответы (1)


Да, это возможно. Набор ключей по определению может содержать несколько ключей. Один из них основной, остальные активные. Первичный ключ может подписывать и проверять, а активные — только проверять.

Вот как это сделать:

1/ Создайте новый KeysetHandle, содержащий два ключа, используя Диспетчер ключей:

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

2/ Получить KeysetHandle из KeyManager

KeysetHandle kh = km.getKeyHandle()

3/Зашифруйте и запишите его в файл JSON, как вы сделали в своем коде.

Надеюсь, это поможет, Тай.

person Thai Duong    schedule 31.01.2019
comment
Спасибо за ответ Тай. Что-то я не понимаю, откуда вы передали kh в аргументах. KeysetManager km = KeysetManager.withEmptyKeyset(kh); Для этого мне нужно сначала создать keysetHandle? Если это так? Тогда какой смысл это делать? KeysetHandle kh = km.getKeyHandle() Поскольку у меня уже есть дескриптор набора ключей. - person Muhammad Umer; 31.01.2019
comment
Также у него нет метода addNewKey(). Единственный метод, который я могу найти, это add(), который принимает KeyTemplate в качестве аргумента. Может проблема с версией? Я использую 1.2.2 - person Muhammad Umer; 31.01.2019
comment
Мухаммад: о, извините, я не заметил, что addNewKey является приватным. Во всяком случае, я обновил свой пример кода, который теперь показывает, как добавить два ключа. Это работает для вас? - person Thai Duong; 31.01.2019