No, you don't encrypt IVs. They need to be never, ever reused, but that's pretty much it for IV requirements for CTR mode -- there's absolutely no need to keep them confidential. Moreover, you affirmatively shouldn't encrypt your IV with the key used to encrypt your message -- depending on your padding scheme, that can very well expose one of the blocks of your message. Under no circumstances will it improve security; any vulnerability in CTR mode will be a vulnerability here as well.
Recall how CTR mode works. In CTR mode, the actual data is never passed as input to the block cipher. Instead, you concatenate a shorter-than-block IV and a shorter-than-block counter, encrypt that, and XOR with the data. An attacker who recovers the encryption of IV||n
can recover the n-th block.
Now, you can't encrypt the IV by itself. It's actually impossible: the IV is sub-block-length, and AES is incapable of encrypting anything that isn't an exact multiple of the length of a block. You need to pad your IV to encrypt it (the reason CTR normally doesn't use padding is that you don't pass the data to AES; if you did, you would need padding). Suppose your padding scheme pads with zeroes and then tacks the length of the message on the end (all common padding schemes have to have the message length show up somewhere, because if you just zero-padded then "john0" and "john" would both become "john000...000"). For your 64-bit IV, the padding would turn IV
into IV||0x00...01000000
; you would then encrypt that and tack it on the start of your message. But the encryption of that is exactly what you XOR with the 64th block of your message. So by encrypting your IV here, you revealed the 64th block of your message, whereas with an unencrypted IV it was secure.
(incidentally: When people say "don't roll your own crypto, it's easy to make subtle mistakes," this is one such subtle mistake. If you're new to crypto, it might seem more secure to encrypt your IV. You have to pad it, so you might pick the fairly reasonable-seeming zero padding with a length tag. Doing so here lets an attacker read a block of your ciphertext.)
The only way around this is to pad such that the padded IV will never be encrypted to generate keystream material. Pretty much the best way to achieve this is to agree on IV length or send IV length cleartext, encrypt all zeroes for the first block, and then not send the IV (on the other end, the decrypted first block gives IV|0x00...01
, which you can take the first bunch of bits for to get the IV). Any encryption of the IV, if the padding scheme is "stick this stuff which is k
in hex, on the end of the IV", is equivalent to making block k
consist of all zeroes. If you look at it like this, you can see that just about any CTR vulnerability will also affect your scheme. The only vulnerabilities related to the attacker knowing the IV, on the other hand, would indicate a serious flaw in AES itself, one which means any scheme using it is instantly suspect.
So no, it's a bad idea to encrypt the IV. If you must do it, the way to do it is to make the first block of your message all zeroes, not send the IV, and on the other end decrypt the first block and take the first 64 bits (or however long your IVs are) as your IV; that won't be less secure than regular CTR. However, it won't be more secure either, because any flaw in AES-CTR related to the IV makes all AES modes presumptively unsafe.
ECDHE-ECDSA-AES128-GCM-SHA256
, which is based on elliptic curves and have bit lengths on par with symmetric encryption). Second, even then it doesn't matter because 4,096-bit RSA is fine — the bit length is almost entirely irrelevant as long as it's large enough to provide the margin of security you're looking for given the choice of algorithm. And regardless, whatever home-brew system you concoct is infinitely more likely to be a source of weakness than 4,096-bit RSA keys.