This might be a question out of left field... but ...
# grpc
c
This might be a question out of left field... but I'll ask it anyway. So I've never used grpc before, but I feel like I sorta get the point of it. I'm using googles encryption library called tink which apprently saves stuff into a protobuf format (kinda cool), but now all I want to do is grab a "deserialized" version of the public key generated by tink which is "KeyData value is still a binary serialized proto." Can I just put a string value of
EgYIARABGAIaILk8CE7/WHIslvUnsNk+ZYNVF0XTTwCQzAD8xqk7K81G
through a protobuf deserializer? I guess i have the proto file so it should be possible? https://github.com/tink-crypto/tink-java/blob/main/proto/tink.proto
j
you can try protobufpal
c
Yeah I tried that and it failed unfortunately
Here is the full public_key.json
Copy code
{
  "primaryKeyId": 1358657949,
  "key": [
    {
      "keyData": {
        "typeUrl": "<http://type.googleapis.com/google.crypto.tink.HpkePublicKey|type.googleapis.com/google.crypto.tink.HpkePublicKey>",
        "value": "EgYIARABGAIaIJn0ZHt4NmblUzZZP/NKmNyHB1A+FOPTajWZU4igYNtY",
        "keyMaterialType": "ASYMMETRIC_PUBLIC"
      },
      "status": "ENABLED",
      "keyId": 1358657949,
      "outputPrefixType": "TINK"
    }
  ]
}
and the tink proto is above. and protobufpal just fails to decode
j
seems like the message is HpkePublicKey, but I can't find it in the definition you provided
also, it seems a bit short for a public key 🤔
c
If this piques your curiosity, you can generate a tink keyset on your own machine 1. Install tink via brew available here: https://developers.google.com/tink/install-tinkey 2. Create keyset via tinkey
Copy code
tinkey create-keyset \
  --key-template DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM \
  --out-format json \
  --out keyset.json
3. Generate json file with public keyset from the previously created keyset.json
Copy code
tinkey create-public-keyset --in keyset.json --out public.json
4. Inside of public.json you will find the base64 key value
but yeah. overall. im just confused how https://developers.google.com/tink/wire-format states that "Note that the KeyData value is still a binary serialized proto." and how im supposed to unpack that proto. lol
j
OK so I think I've solved the mystery The JSON you've provided earlier is a message of type
Keyset
, it contains an array of
Key
, which contains a
KeyData
The content of your
KeyData
is what you found in the
key_data
field:
Copy code
{
  "primaryKeyId": 1358657949,
  "key": [
    {
      "keyData": {
        "typeUrl": "<http://type.googleapis.com/google.crypto.tink.HpkePublicKey|type.googleapis.com/google.crypto.tink.HpkePublicKey>",
        "value": "EgYIARABGAIaIJn0ZHt4NmblUzZZP/NKmNyHB1A+FOPTajWZU4igYNtY",
        "keyMaterialType": "ASYMMETRIC_PUBLIC"
      },
      "status": "ENABLED",
      "keyId": 1358657949,
      "outputPrefixType": "TINK"
    }
  ]
}
which, essentially, is this part:
Copy code
{
  "typeUrl": "<http://type.googleapis.com/google.crypto.tink.HpkePublicKey|type.googleapis.com/google.crypto.tink.HpkePublicKey>",
  "value": "EgYIARABGAIaIJn0ZHt4NmblUzZZP/NKmNyHB1A+FOPTajWZU4igYNtY",
  "keyMaterialType": "ASYMMETRIC_PUBLIC"
}
If you check the definition of the
value
field, you will see it is defined as a
bytes
type : https://github.com/tink-crypto/tink-java/blob/14dfd36a2e3ad8c36bd35bf9ef0046f97cf9a390/proto/tink.proto#L119 the value is an opaque byte array, you can't go further
the value you've provided in your first message
Copy code
EgYIARABGAIaILk8CE7/WHIslvUnsNk+ZYNVF0XTTwCQzAD8xqk7K81G
it's not a
KeyData
message, it's the value contained within the
KeyData
message
c
... 👀
okay, i read that a few times, but i still feel like im missing something. how do i actually get the base64 key out of that?
j
what value do you want to obtain? If you're searching for the value of your key, then it seems to be that one:
Copy code
EgYIARABGAIaILk8CE7/WHIslvUnsNk+ZYNVF0XTTwCQzAD8xqk7K81G
here it's the base64 representation, but you can convert it to a byte array
c
yeah so i need the base64'd version, but my server doesn't accept it. my server team said its because when i send the base64 version it's actually still a proto
Which seems to match what tink docs state... that its still a proto?
j
oooh, right!
however they don't provide the message definition?
c
right!?!
j
this tool allows you to decode a protobuf message without it's schema
you can see the field
3
is a byte array
this might be your value
c
🤯
Okay, so now I guess I gotta figure out how to do that in kotlin
i kinda dont understand how there are two fields (named 2 and 3 respectively) but maybe thats a protobuf thing
j
🥳
the
public_key
field is the `3`rd one
it contains your key
c
OH HOT DAMN
okay, so i can ship the hpke.proto within my kotlin app, use that to decode the public key value (like
EgYIARABGAIaILk8CE7/WHIslvUnsNk+ZYNVF0XTTwCQzAD8xqk7K81G
) and then I should be able to grab the actual public key
THANK YOU SO MUCH
❤️ 1
I owe you a beer (many) or coffee. if you have a buymeacoffee or anything please send it over. this has been KILLING ME
should have known to look for another proto. lol
j
haha, don't worry, I'm happy to be helpful ^^
c
I have to actually try this in practice (later) today in kotlin code, so ill be back here if i come across any hiccups, but yeah this seems like it should be it. As long as I can take this last byte array and base64 it, then i should be all set. i honestly don't typically work with binary data, byte arrays, base64 etc, so I'm just assuming there should be a way to go from byteArray to base64. lol
so far just trying to blindly throw that public_key into a byte array is a no go
j
because the byte type is signed, its range is -128 to 127 😉
you have to shift all your values
or use UByte
but you also could provide the hexadecimal string and convert it to a byte array!
a
I used tink for my slack kmp project and regretted.. since it’s ios support with cocoapods had an issue .. i ended up using my own solution.. with chacha20 and RSA https://github.com/oianmol/SlackComposeMultiplatform/tree/project_revamp_march_2024/capillary-kmp
c
yeah. tink is weird. on the other hand. it is quite an ambitious project. and im sure thats hard to get right.
Hey @Johann Pardanaud I'm kind of veering off the topic of protobufs... but im still working on this from 4 days ago so I figured I'd ask here since we had a pretty good exploration session before. The thing I'm basically trying to do is get my ciphertext and pull out the individual pieces of it. i.e.
Copy code
val cipheredTextWireFormat: ByteArray = encryptor.encrypt("hello".toByteArray(), ByteArray(0))
println("got ciphered text hex")
println(cipheredTextWireFormat.toHexString())
Output:
Copy code
got ciphered text hex
016b099f30d906625582c02234ca9ea6852831edd6c85c3dcb4bdbaf20d9c9c66e1858de13ee00e35898c65cfc836f8afebbfa71336a283ec1f0
According to the docs... the ciphertext wireformat for Hybrid encryption is
Copy code
prefix || encapsulated_key || encrypted_data
So now I'm kinda stuck on trying to extract
encapsulated_key
and
encrypted_data
from that cipheredTextWireFormat Any chance you know how to pull those two values out?
j
This page describes Tink's wire format for keys and primitive output. The documentation is aimed at cryptographers who want to add additional languages to Tink and maintainers of other high-level crypto libraries who want a wire compatible mode. It is not intended for general audiences.
are you SURE you need to extract the encrypted data from the binary? 😄
I don't really know anything about Tink, but it seems like this value should be considered "opaque" and only readable by Tink?
Honestly, I can't really help here. The prefix can be present or missing, the encrypted_key should contain the length of encrypted_data, but what is the length of encrypted_key? I really don't know how to decode this binary value, or I would have to spend hours on this task 😅
c
all good. just wanted to saniyt check to make sure it wasn't something simple. appreciate your two cents!
👍 1
oh. i think i know what i can do. since this is open source i can try to trace/debug the tink code to see how it encrypts things... hm. maybe thats a gameplan.
okay. i think im getting somewhere. looks like these are just byte arrays concatenated. nothing fancy. no pipe characters or anything. the only thing i can't seem to figure out is "prefix", but trying to look into the tink code to see if I can figure it out
👍 1