I need to send a lot of small messages that are usually between 128 bits and 256 bits long, and each message is encrypted with a separate 128 bit AES key. Therefore, to send each message with the key would require between 256 and 384 bits of data. If a message is 129 bits long, it would still take 2 AES blocks to encrypt and the message size with the key would increase to 384 bits.

Because of this, I'm thinking I can increase throughput by using AES as a stream cipher. The solution I came up with is simply to use the key to encrypt a message of all 0's with size rounded up to the nearest 128 bits, using AES and a suitable non-authenticated encryption mode like CTR. Then, take the encrypted zeroes and XOR them with the plaintext to get a same sized ciphertext. I realize each key may only be used once, because given the plaintext and ciphertext, the stream can be recovered, but this is not a problem in my situation because each key is only used once. My question is, is this method secure, and does it have any other caveats such as the plaintext attack I mentioned?

1 Answer
1

CTR mode is about encrypting data by generating a key dependent pseudo-random stream and XORing it with the data; so what you describe really is CTR mode, and you don't have to to the XOR yourself. Said otherwise, by encrypting a bunch of zeros and then XORing the result with your actual data, you are just doing a needless extra XOR with zeros.

(You are highly encouraged not to try to invent encryption modes by yourself if you do not completely master the design of cryptographic modes, and the people who are qualified to perform such designs actually consider wisely that even they cannot reliably do the job properly.)

CTR mode is highly vulnerable to key reuse, so you'd better make sure that you, indeed, never reuse a key value; alternatively, you may reuse a key if you use a "sufficiently distinct IV" (since CTR works by encrypting successive values of a counter, you can get away with reusing a key as long as you do not reuse a counter value), but the IV must be known to both sender and receiver, which may be a problem in some use cases (adding an explicit IV to each message increases size; implicit IV such as message counts cannot necessarily be used if messages can be lost or receivers are stateless). Apart from that, an unauthenticated mode has the generic weakness of, indeed, not being authenticated, which can be very troublesome when there are active attackers roaming around (and scenarios with passive-only attackers tend to be unrealistic). Also, CTR mode implies no padding, so the encrypted data length is equal to the plaintext data length, which is what you want, but also means that the plaintext data length leaks -- depending on your context, this may or may not be a problem.

Within the limits expressed above, CTR mode is as good as such things can get.