Background
I'm trying to design a secure and sustainable web app for messaging. The purpose is to learn how to create secure web application.
The application is suppose to be written in Javascript for web based clients and PHP for server-side.
Clients using the web application will log in to be able to use the service on a wide variety of devices.
Clients can then send messages to other users - securely without any middle hand being able to read the message in clear text. I don't want the server to be able to read the messages either, therefore the main encryption will have to happen client-side.
Thoughts
- SSL/TLS - ensure valid communication with server
- RSA - asymmetric encryption - for encrypting encryption keys
- AES - to encrypt unknown amount of data, most commonly plain text
The whole application will obviously be built using SSL / TLS to allow secure and validated communication between the client and the server.
To ensure that only the intended parties get access to the sent data, asymmetric encryption is used. Every client has their own private keys stored client-side and their public keys stored on the server attatched to the user in a database.
When Alice wants to write a message to Bob, she encrypts the data with a strong AES key - since RSA can only handle a finite data size. To ensure that only Bob can read the message, she retrieves Bob's public key from the database and encrypts her generated AES key with it. The encrypted message is then sent to the server - along with the key used - encrypted with Bob's public key.
Bob retrieves this message / key pair from the server. Since Bob has the private key related to the used public key for encrypting Alice's message's key - he and only he can retrieve the used key in plain text. Using this unencrypted key he can then decrypt the main message and read it as plain text.
Concerns
The public and private key pair has to be generated server-side. This forces the private key to be sent to the user for use. How can this be made safe, since any middle-man can retrieve the private key to further use to decrypt all of Alice's messages.
To ensure that the server doesn't know what messages users send, it cannot have access / store the private keys. This forces the keys to be stored client-side - using Javascript, a language and platform rarely associated to security or secure data persistence. Since security is of my main concern, not properly storing the private keys is a major problem.
Let's say the user wants to log in and use the application from another device, then the private key has to 'magically' appear there as well. Forcing the server to store the private keys anyway. Is there any other way to do this encryption / key management?
Clarifying questions
If the above topics are too long to read, confusing or if you're just in a hurry, below are simplified questions.
How can I ensure messages being sent between can only be read by those two parties?
How can I ensure my users that I / the server or anyone else for that matter, can read their messages?
If their is a way of storing the private keys securely client-side, how bad is it?