views:

172

answers:

1

I am trying to encrypt data with a password and store it inside a ASN.1 encoded CMS message (using C# and BouncyCastle 1.4)

The code I have seems to have two problems:

  • the data does not seem to be signed with a HMAC, so when I tamper with the encodedData (by enabling the commented out line), the decryption still succeeds.

  • when I decrypt the data I have tampered with, I get beck corrupted plain text. However only a two blocks of plaintext data are corrupted. This seems to suggest that the encryption does not actually use CBC mode.

    (edit: disregard the second point, this is exactly how CBC is supposed to work)

This is what I am testing with:

public void TestMethod1()
{
    byte[] data = new byte[1024]; // plaintext: a list of zeroes

    CmsEnvelopedDataGenerator generator = new CmsEnvelopedDataGenerator();
    CmsPbeKey encryptionKey = new Pkcs5Scheme2PbeKey("foo", new byte[] { 1, 2, 3 }, 2048);
    generator.AddPasswordRecipient(encryptionKey, CmsEnvelopedDataGenerator.Aes256Cbc);
    CmsProcessableByteArray cmsByteArray = new CmsProcessableByteArray(data);
    CmsEnvelopedData envelopeData = generator.Generate(cmsByteArray, CmsEnvelopedDataGenerator.Aes256Cbc);

    byte[] encodedData = envelopeData.GetEncoded();

    // encodedData[500] = 10; // tamper with the data

    RecipientID recipientID = new RecipientID();
    CmsEnvelopedData decodedEnvelopeData = new CmsEnvelopedData(encodedData);
    RecipientInformation recipient = decodedEnvelopeData.GetRecipientInfos().GetFirstRecipient(recipientID);

    byte[] data2 = recipient.GetContent(encryptionKey);

    CollectionAssert.AreEqual(data, data2);
}

What am I doing wrong? What would be the correct way to write this?

+1  A: 

To add an HMAC to a CMS message, you would have to use a AuthenticatedData-structure.

I am not especially familiar with Bouncy Castle, but from a cursory look at the API, I would say that it does not support AuthenticatedData. In fact, it looks like it only supports SignedData for authentication.

So your options seems to be:

  1. Use another library (or write your own code) to handle the AuthenticatedData-structure.
  2. Calculate the HMAC and provide it in a non-standard way (in a proprietary Attribute or out-of-band).
  3. Use SignedData with an RSA key pair instead.
Rasmus Faber
Thank You. The CVS version of BouncyCastle C# seems to have support for AuthenticatedData and the Java Version of the Library also seems to implement this. This looks like the way to go. Investigating.
levinalex
I opted to roll my own and just add a checksum to the message before I put it in the CMS data structure. Bouncycastle C# (dev version) has parsers for AuthenticatedData structures but for now lacks a easy to use generator.
levinalex