Skip to content

Instantly share code, notes, and snippets.

@ewa
Created January 26, 2016 00:15
Show Gist options
  • Save ewa/513a87ae1b1b7868d62a to your computer and use it in GitHub Desktop.
Save ewa/513a87ae1b1b7868d62a to your computer and use it in GitHub Desktop.
Cleanly handling encrypted data in protocol buffers or similar

Cleanly handling encrypted data in protocol buffers or similar

Posted on Stack Overflow here.

Is anyone aware of a library / wrapper for working with encrypted and/or signed data in protobufs (or other similar message description & serialization tools)?

I keep finding myself dealing with messages where all or part of the message is encrypted, like so:

message ThisIsCleartext {
    optional SomeUnencryptedStuff bar = 1;
    optional bytes cyphertext = 2;
}

message ThisIsEncrypted {
    optional SomethingSensitive baz = 1;
    optional SomethingElse quux =2 ;
    // etc.
}

I’d build them like so:

a = ThisIsEncrypted()
a.baz = something
a.qux = something_else

a_str = a.SerializeToString()
a_enc = SomeEncryptionFunction(a_str, key)

b = ThisIsClearText()
b.bar = whatever
b.cyphertext = e_enc

(Plus some boilerplate like nonces, tags for what cryptosystem is used, etc.)

To access the data, the process is reversed: Access the cleartext protobuf b, pull out the cyphertext as a string/byte array, decrypt it separately, then parse that string to get the (formerly) encrypted protobuf message a.

This works fine, but it’s not particularly elegant, and nothing enforces that bytes cyphertext is actually what it’s supposed to be: an encrypted representation of a ThisIsEncrypted.

Do you know of something better? In my fantasy world, I’d be able to write something like:

message Foo {
    optional SomeUnencryptedStuff bar = 1;
    encrypted (cipher_spec) c {
        optional SomethingSensitive baz = 3;
        optional SomethingElse quux = 4 ;
    }
}

and access it like:

a = Foo()
a.bar = this
a.c.baz = that
a.c.quux = the other thing

msg = a.SerializeToString()
## Whoops!  That's BS.  Not encrypted.  Throws an error

a.c.Encrypt(some parameters, some keys, some nonces, whatevs)
msg = a.SerializeToString()
## Ok, that works.  a.c contains the cyphertext and tags and stuff

b = Foo() 
b.ParseString(msg)
print b.c.baz
## Whoops! Can't access encrypted data
b.c.Decrypt(some keys)
print b.c.baz
## ok 

Is there anything like that out there? If not, are there any obvious barriers to implementing it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment