I wrote a chat program for fun that addresses the problems. See https://github.com/akc42/MBChat. The software originated as a non secure chat for a fan club (www.melindasbackups.com) that I an the IT director for, but I tried to add security to it as part of a proof of concept for use where people were trying to intercept the comms.
The assumption I made is that all communication between client and server needed to be secure and that there could always be a man in the middle trying to intercept your communication. Since the initial program is downloaded from the server, it is not possible to send the keys needed to encrypt things with the program.
My solution to this was to calculate a RSA key pair on the fly in the browser as the program starts up - and then send the public key to the server and ask it to encypt the key used for communication using this public key. The client then decrypts it using his private key.
Because RSA key pair generation is quite compute intensive - I had to develop a mechanism (which I borrowed from elsewhere) to allow the browser to perform long running calculations without timing out. It does this by breaking things down into small steps and returning to browser for a "tick".
I also spent some time trying to have the server also prove it was the correct server. I came to the conclusion that the only completely foolproof way required each human client to know the "Standard message of the day" and to be able to see it after its been decrypted for the server comms to be sure the server is who you think he is.
I open sourced it when I developed it about two years ago now - but I don't think anyone has cloned it or taken a look.