I'd take the following steps to send/received data between client and server. But I'm not sure if all the steps are secure enough and impossible to intercept. Please can you let me know how to patch up the security holes, if any?
Please note that:
This is all for Symmetric cryptography not the Public/Private Key method. So 'salt' and 'entropy' are the secrets between client and server.
For some reasons, I cannot/don't use SSL or TLS protocols. So there is no Certificate Authority etc.
Only standard cryptography functions and methods must be used (no inventions).
The data are not sent over a secure (HTTPS) connection.
I cannot use sessions here because they are two different applications.
First time - Sign up (user enters new username and new password)
- Client side
- Create a CSPRNG salt for the user
- Save salt on user's machine
- Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
- Post Password(base64 of the plaintext), and salt, and entropy to the server
- Server side
- For the received message from the cliet
- Check if entropy matches (e.g. with base64 of [hour of the day]+[day of the year]) .
- Compute hash (SHA1) of salt and Password(base64 of the plaintext) - because hashing must always be done on the server.
- Save salt and the computed hash to the database
Next time - Log in (user enters his username and his password)
- Client side
- Read salt from user's machine
- Compute hash (SHA1) of salt and entered password(base64 of the plaintext)
- Post password(base64 of the plaintext), and salt, and the computed hash to the server
- Server side
- Retrieve salt and 'stored hash' from the database
- From the received message from the client
- Split the message to 3 parts: password(base64 of the paintext); salt; 'received hash'
- Compare 'received hash' with 'stored hash'; if they match, the user is genuine not a hacker
Sending TemperProof queryString from user to server
- Client side
- Read salt from user's machine
- Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
- Compute hash (SHA1) of the queryString(base64 of the plaintext), and salt, and entropy
- Post querystring(base64 of the plaintext), and salt, and entropy, and the computed hash to the server
- Server side
- Retrieve salt from the database
- For the received message from the cliet
- Split the message to 4 parts: queryString(base64 of the paintext); salt; entropy; 'received hash'
- Check if entropy matches (e.g. with base64 of [hour of the day]+[day of the year]) .
- Compute hash (SHA1) of queryString(base64 of the plaintext) and salt and entropy.
- Compare the computed hash with the 4th part of the splitted message ('received hash'); if they match, the queryString is genuine
Sending answer back to the user from server
- Server side
- Compute the answer using database queries
- Retrieve salt from the database
- Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
- Compute hash (SHA1) of the answer(base64 of the plaintext), and salt, and entropy
- Post answer(base64 of the plaintext), and salt, and entropy, and the computed hash to the client
- Client side
- Read salt from user's machine
- Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
- Split the received message to 4 parts: answer(base64 of the paintext); salt; entropy; 'received hash'
- Check if entropy matches (e.g. with base64 of [hour of the day]+[day of the year]) .
- Compute hash (SHA1) of answer(base64 of the plaintext) and salt and entropy.
- Compare the computed hash with the 4th part of the splitted message ('received hash'); if they match, the answer is genuine
The followings areas are the weaknesses, I think. Can you please advise how these can be fixed and also point out the other possible holes?
A) First time - Sign up: The hacker can post rubbish to fill up the database, if he finds entropy in step 1.3
B) Next time - Log in: I cannot think of a way to add an entropy to the hashed password in step 1.2, because then I cannot compare with the one on the server database in step 2.2.2
Thanks