Here is my code
KeysetHandle handle = KeysetHandle.generateNew(KeyTemplates.get("AES256_GCM"));
Aead aead = handle.getPrimitive(Aead.class);
How can I get the byte /string representation of the key tha KeysetHandle uses here?
Here is my code
KeysetHandle handle = KeysetHandle.generateNew(KeyTemplates.get("AES256_GCM"));
Aead aead = handle.getPrimitive(Aead.class);
How can I get the byte /string representation of the key tha KeysetHandle uses here?
My answer is a little bit tricky and "hacky" but it works in my cases.
Google Tink tries to avoid any direct contact to the key data so there is no direct access to the data but with a little trick using a combination of "ByteArrayOutputStream" and "ObjectOutputStream" you are been able to retrieve the data as JSON string or byte array.
Kindly note: my source code does not handle any exceptions and the usage of strings as holder of keys is discouraged.
This is the function to archive the data from a keysetHandle:
public static byte[] keysetHandleToByteArray(KeysetHandle keysetHandle) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
CleartextKeysetHandle.write(keysetHandle, JsonKeysetWriter.withOutputStream(oos));
oos.close();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Just call the method with your generated keysetHandle like:
byte[] keysetHandleDataByte = keysetHandleToByteArray(handle);
As the data is a JSON byte array (or string) you need to find the field "value" - here is a sample keysetHandle in JSON encoding:
{"primaryKeyId":730264253,"key":[{"keyData":{"typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey","value":"GiBglVZ0+LFaeCVo/fL1liC/KMqRw8WM5cJtdv5Dh4e5FQ==","keyMaterialType":"SYMMETRIC"},"status":"ENABLED","keyId":730264253,"outputPrefixType":"TINK"}]}
Just for convenience - here is a "rough" function that extracts the key value - beware that strings are inmutable when using key material:
private String searchDataInJson(String jsonString, String searchString) {
// find position of searchString in the jsonString
int pos = jsonString.indexOf(searchString);
if (pos > -1) {
// searchString found, get length of searchString
int searchStringLength = searchString.length();
// add searchStringLength to pos to get first data
pos = pos + searchStringLength;
// search for next " in jsonString as end position
int endPos = jsonString.indexOf("\"", pos);
if (endPos > -1) {
// endPosition of datafield found
String dataString = jsonString.substring(pos, endPos);
return dataString;
}
}
// nothing found...
return "";
}
Call this function like this and you retrieve the generated AES GCM 256 key in Base64 encoding:
String keysetHandleDataString = new String(keysetHandleDataByte);
String keyMemoryBase64 = searchDataInJson(keysetHandleDataString, "value\":\"");
System.out.println("keyMemoryBase64: " + keyMemoryBase64);
The result will be (again sample data):
keyMemoryBase64: GiBglVZ0+LFaeCVo/fL1liC/KMqRw8WM5cJtdv5Dh4e5FQ==