[Botan-devel] Problem with encrypting and decrypting serialized data

Jack Lloyd lloyd at randombit.net
Wed May 19 09:42:33 EDT 2010

On Sat, May 15, 2010 at 05:19:23AM +0200, Micha?? P??oski wrote:
> Hi everyone. I faced the big problem I cant solve for few days.
> I have input data unsigned char serializedUdp[] which are serialized. I 
> need to encrypt this data ,pass to other function and then decrypt and 
> get the same data what in input. After that data should be mapped to 
> structure.
> Problem is that whatever im trying to do serialized data after 
> decryption are diffrent than imput.

Your code looks fine from a quick look. I'd say you have to narrow
down the problem:

Is the problem that CBC decryption throws an exception? By default CBC
mode will pad some extra bytes at the end (because CBC can only
encrypt a full block at a time, 16 bytes in the case of AES), which it
will check on decrypt. Also, are you sure you are not truncating?
Since the result of encrypting with CBC will be larger than your
original input; if you remove the last bytes from the ciphertext,
you'll get a decrypt error.

Are you sure your serialization/deserialization routines actually
round-trip properly? For instance, if you just comment out the actual
encryption/decryption operations, you do get the correct values?

Are you sure your keys/IVs match on both sides? An easy way to check
is to print them to stdout:

  std::cout << "My key is " << key.as_string() << "\n";

Printing the plaintexts and ciphertexts on each side may also help
track down the problem.

An aside on performance; you don't need to put serializedUdp into a
DataSource_Memory, and actually if you're doing a network app avoiding
this seems highly worthwhile, because it will involve doing an extra
allocation and copy for each packet. Instead you can just pass
serializedUdp and length to process_msg(). Also caching the Pipe will
help greatly, since acquiring a new cipher object and running the AES
key schedule will easily add 10K cycles to each packet processing.
Obviously first just getting something that works is useful, but I
thought it worth mentioning.

An aside on security: you really want to use a MAC in addition to
encryption; otherwise it is trival to perform various bit-flipping
attacks. An easy way to do this is to simply use AES-128/EAX instead
of AES-128/CBC. It will add an extra 16 bytes (the authentication tag)
at the end of the ciphertext; if packet space is truly an issue you
can reduce this by passing a parameter to EAX, for instance
"AES-128/EAX(80)" will produce a 80-bit (10 byte) tag. Don't go below
64 bits though.


More information about the botan-devel mailing list