I need to encrypt 20 bytes of data and the encrypted nonce + data + mac cannot exceed 30 bytes in size. I have an implementation but i'm not sure if i'm cutting too many corners and compromising encryption.
Using the bouncy castle library i was able to write this.
static (byte[],byte[]) encrypt(byte[] data, byte[] key, byte[] nonce)
{
var engine = new AesEngine();
var parm = new AeadParameters(new KeyParameter(key), 16, nonce);
var chipher = new CcmBlockCipher(engine);
chipher.Init(true, parm);
var output = new byte[chipher.GetOutputSize(data.Length)];
var outputLength = chipher.ProcessBytes(data, 0, data.Length, output, 0);
chipher.DoFinal(output, outputLength);
return (output, chipher.GetMac());
}
Here is my thinking. For the data encrypted i have the following pieces of information known:
- Metadata about the origination of the data
- The approximate date the data was encrypted (down to the day)
With that information i formulated a nonce that contains:
2 bytes meta + 8 bytes Unix ms timestamp
With that i'm able to chop off all but the last 4 bytes of the nonce as those are the least significant bytes that indicate a timestamp for the day in question.
With that in mind i can have the final full encoded data as:
4 byte nonce + 20 byte encrypted + 2 byte MAC
This makes it fit under the 30 byte limit.
So here are my questions:
- Is a 16 bit MAC effective at all in this scenario?
- Is it kosher to create a nonce from partially known data?
- How can i verify that my nonce is being incremented properly inside the code? I just appear to pass a static nonce even though its supposed to increment according to CTR... right?