Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google/Tink: How use public key to verify signature

We want to use the Tink library in our project to be able to verify some incoming signatures given a public key.

What we have are the following:

  1. The public key as a string
  2. The signature itself
  3. The plaintext

After going through Tink's documentation, we cannot figure out how to load the public key string so that it can be used by PublicKeyVerifyFactory.

Has anybody done anything similar? Have you found any examples online that could point us to the right direction?

like image 212
Alex Ntousias Avatar asked Nov 09 '18 15:11

Alex Ntousias


1 Answers

You can create a KeysetHandle from a public key through CleartextKeysetHandle.read(), then get it's primitive and then verify the signature. You don't need to know the private part of the KeysetHandle to do that, which is the point of using asymmetric keys in the first place.

The question is, what should I export in order to use this read() later? There are several ways, but one way is to export the PublicKeysetHandle to a JSON format. You export it using CleartextKeysetHandle.write() with JsonKeysetWriter.withOutputStream(), and you can later convert it back to a KeysetHandle using CleartextKeysetHandle.read() with JsonKeysetReader.withBytes().

So, you are Bob and want to public your public key to Alice. In your service you will generate your private key, extract the public key, convert it to a JSON format and export that in some way, like a REST endpoint:

Bob's application

SignatureConfig.register();

// This is your, and only yours, private key.
KeysetHandle privateKeysetHandle =
    KeysetHandle.generateNew(SignatureKeyTemplates.ECDSA_P256);

// This is the public key extracted from the private key.
KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle();

ByteArrayOutputStream publicKeyStream = new ByteArrayOutputStream();

CleartextKeysetHandle.write(publicKeysetHandle,
    JsonKeysetWriter.withOutputStream(publicKeyStream));

// And this is the public key in JSON format.
// You can publish this in a REST endpoint.
return publicKeyStream.toString();

Alice's application

String publicKey = getThatJsonPublicKeyFromBobsEndpoint();

// Here the JSON with only the public key is converted into a KeysetHandle.
KeysetHandle keysetHandle = CleartextKeysetHandle
    .read(JsonKeysetReader.withBytes(publicKey.getBytes()));

// Getting the signature verifier from the public keyset handler.
PublicKeyVerify verifier = keysetHandle.getPrimitive(PublicKeyVerify.class);

// And finally verify Bob's signature for his message.
verifier.verify(bobsMessage.getSignature(), bobsMessage.getData());

In Bob's application the private key is being generated every time. You may want to stick with the same private key, so you'll need to store that private key and restore it just like the Alice's application, but instead using the PublicKeysetHandle you would use the PrivateKeysetHandle. The examples above are just to show how to export the public key into a string format and restore it later in another application.

like image 110
Rafael Renan Pacheco Avatar answered Sep 23 '22 14:09

Rafael Renan Pacheco