tink icon indicating copy to clipboard operation
tink copied to clipboard

StreamingAead with KEK URI

Open mayurpr opened this issue 3 years ago • 2 comments

Currently tink has only Aead KEK URI support. Is there any example or support for StreamingAead with KEK URI?

below example is only having Aead as primitive, but we want to use StreamingAead with KEK URI. https://github.com/google/tink/blob/master/examples/java_src/encryptedkeyset/EncryptedKeysetExample.java

if i try to use this snippet

                   StreamingAead aead = null;
		KeysetHandle handle;
		try {
			handle = KeysetHandle.generateNew(KmsAeadKeyManager.createKeyTemplate(kekUri));
			aead = handle.getPrimitive(StreamingAead.class);
		} catch (GeneralSecurityException ex) {
			throw ex;
		}

to get StreamingAead instance i get below exception.

java.security.GeneralSecurityException: Primitive type com.google.crypto.tink.StreamingAead not supported by key manager of type class com.google.crypto.tink.aead.KmsAeadKeyManager, supported primitives: com.google.crypto.tink.Aead

Thanks for making this awesome lib :)

mayurpr avatar Jul 06 '21 07:07 mayurpr

I'm having the same issue. A different application is writing to GCS using StreamingAead. And a different application is reading the encrypted file. Streaming AED works when I'm using the same KeysetHandle when encrypting and decrypting the file.

	    	KeyTemplate theKeyTemplate = KeyTemplates.get("AES256_GCM_HKDF_1MB");
	    	KeysetHandle theHandle = KeysetHandle.generateNew(theKeyTemplate);

I'm just starting out on using Tink and GCP in general, so possibly I'm missing something obvious.

I think I can store the keys in KMS (https://github.com/google/tink/blob/v1.2.2/docs/JAVA-HOWTO.md#storing-keysets). But I wonder why I can't use the KEK URI for streaming Aead like I can for Aead.

Edit: This link and the corresponding GitHub code helped me figure it out. https://medium.com/12-developer-labors/envelope-encryption-with-google-tink-and-gcp-key-management-with-example-a738632434da

milindrao avatar Sep 15 '21 16:09 milindrao

Hello, I'm searching for the same functionality.

I currently have some code (in golang in my case) using the AEAD envelope with a Google KMS Key URI, which works very well, but I'm trying to do the same with a streaming AEAD instead.

Is it possible?

lcguida avatar Aug 29 '22 14:08 lcguida

I'm also interested in having a StreamingAead implementation that encrypts a stream using a key encrypted by a KMS. Is this something that is on the Tink roadmap? If not, is this a feature that would be accepted as a contribution?

tmelmoth avatar Dec 12 '22 19:12 tmelmoth

It is currently not possible to create an "EnvelopeStreamingAead" primitive, and we also don't plan to add this functionality. Also, we have some plans to change the API of Envelope encryption, and therefore we prefer not to add any feature to it at the moment.

But you can do almost the same like this: to encrypt using StreamingAead and a KMS key, you do this:

  • create a keyset handle using a StreamingAead template.
  • create an Aead primitive for your KMS key.
  • encrypt the StreamingAead keyset using TinkProtoKeysetFormat.serializeEncryptedKeyset and store it somewhere (or use KeystHandle.write method and the BinaryKeysetWriter.)
  • create the StreamingAead primitive from the keyset handle and encrypt your data.

to decrypt, you do this:

  • create an AEAD primitive for your KMS key.
  • read and decrypt the encrypted StreamingAead keyset using TinkProtoKeysetFormat.parseEncryptedKeyset (or KeysetHandle.read method and the BinaryKeysetReader)
  • create the StreamingAead primitive and decrypt your data.

The code is very similar to https://source.corp.google.com/piper///depot/google3/third_party/tink/java_src/examples/encryptedkeyset/EncryptedKeysetExample.java. (the difference is that I prefer to use binary format instead of Json, because it will be smaller) This should also work in C++, Go and Python.

The only difference to envelope encryption is that you will have to store two files (the encrypted keyset and the encrypted data) instead of just one. But this approach here is a bit more flexible, because you can for example use the StreamingAead primitive several times if you want, which will result in less calls to the KMS.

Does this work for your use case?

juergw avatar Jan 30 '23 14:01 juergw

Hello, the code sample seems to be private. But i'm doing something similar to what you described, storing key sets n a separate bucket and encrypting them with a KMS Key. I also added some code to deal with key rotation.

PS: I was on parental leave, so I took time to go back to the problem ;)

lcguida avatar May 10 '23 17:05 lcguida

To clarify, the code sample referenced above can be found here:

https://github.com/google/tink/blob/master/java_src/examples/encryptedkeyset/EncryptedKeysetExample.java

Or, in its new home here:

https://github.com/tink-crypto/tink-java-gcpkms/blob/main/examples/encryptedkeyset/EncryptedKeysetExample.java

chuckx avatar May 11 '23 02:05 chuckx