For learning purposes, I'm creating a chat application where the connections are done via SSL/TLS, and the messages are encrypted using AES-CBC-256 and the AES keys are encrypted with RSA-2048.

The AES key is randomly generated (AesProvider.GenerateKey()) per user per session (which means one key for every person an user is chatting with) and the IV is randomly generated (AesProvider.GenerateIV()) by passing in the key generated, each time a message is created (before being sent). On the RSA side, I'm generating a secure random session name to store the private keys generated in containers, and sending out the public key. I'm also using the same model (one key pair per user per session) as in AES.

I should also state that I'm using HMAC-SHA512 to hash the messages and sending the HMAC key encrypted using the same public key that the AES key/Iv gets encrypted with. Since I've read that it doesn't need to be regenerated often, I'm planning on regenerate the HMAC key every 5000 or 10000 calls.

Questions: 1) Should I be creating only one RSA key pair per user and use it for all sessions, or is it good how it is right now? 2) Is using the same AES key and only changing the IV like explained above considered secure?

1 Answer 1


Apparently you use RSA to make a key exchange: party A wants to have a shared secret with party B (e.g. a key suitable from some AES or HMAC); thus party A generates a random value K and encrypts K with B's public RSA key. B will use its private RSA key to perform the decryption and recover K.

This process works only as long as party A uses for encryption a RSA public key that really belongs to the intended recipient (B). A might remember B's public key from a previous interaction, or there may be a central trusted repository, maybe a "virtualized" repository (that's what certificates are about). In any case there must be something to prevent attackers from pushing their own, fake RSA public keys in lieu of the genuine ones. This is not an easy problem to solve. If you generate new key pairs on a per-session basis, then that problem will become substantially harder.

Anyway, when you use SSL (which is a good idea), you already get that kind of mechanism for all client-to-server communications. SSL clients use the SSL server's public key (in the server's certificate) to establish a shared secret with that server. You don't see any of this because that's all hidden within the SSL library; but it is there. If you want some extra encryption, then I must assume that you want from user-to-user encryption, because the central server is not trusted. (If you just wanted some encryption between each client and the server, then this would be wholly redundant with the SSL.)

For user-to-user encryption, each user A must somehow know the public key of every other user B that A wants to talk with. Distribution of such public keys is the core problem, because you want to block fake keys, but you do not trust the central server for maintaining order (if you trusted the central server, then you would simply let the SSL do the job). You may want to investigate the notion of Web of Trust for a possible model for decentralized public key distribution.

For symmetric encryption, the whole point of generating new IV is indeed to be able to safely reuse symmetric encryption keys. As long as you generate such IV properly (CBC requires random, uniform, unpredictable IV), this should be fine.

  • Thank you for the explanation, I will take it into account.
    – user91292
    Commented Nov 6, 2015 at 17:31

You must log in to answer this question.