Search code examples
securitycryptographyencryption-symmetric

How to send data in secure way between client and server using only Symmetric cryptography


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)

    1. Client side
      1. Create a CSPRNG salt for the user
        1. Save salt on user's machine
      2. Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
      3. Post Password(base64 of the plaintext), and salt, and entropy to the server
    2. Server side
      1. For the received message from the cliet
        1. Check if entropy matches (e.g. with base64 of [hour of the day]+[day of the year]) .
        2. Compute hash (SHA1) of salt and Password(base64 of the plaintext) - because hashing must always be done on the server.
        3. Save salt and the computed hash to the database

    Next time - Log in (user enters his username and his password)

    1. Client side
      1. Read salt from user's machine
      2. Compute hash (SHA1) of salt and entered password(base64 of the plaintext)
      3. Post password(base64 of the plaintext), and salt, and the computed hash to the server
    2. Server side
      1. Retrieve salt and 'stored hash' from the database
      2. From the received message from the client
        1. Split the message to 3 parts: password(base64 of the paintext); salt; 'received hash'
        2. Compare 'received hash' with 'stored hash'; if they match, the user is genuine not a hacker

    Sending TemperProof queryString from user to server

    1. Client side
      1. Read salt from user's machine
      2. Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
      3. Compute hash (SHA1) of the queryString(base64 of the plaintext), and salt, and entropy
      4. Post querystring(base64 of the plaintext), and salt, and entropy, and the computed hash to the server
    2. Server side
      1. Retrieve salt from the database
      2. For the received message from the cliet
        1. Split the message to 4 parts: queryString(base64 of the paintext); salt; entropy; 'received hash'
        2. Check if entropy matches (e.g. with base64 of [hour of the day]+[day of the year]) .
        3. Compute hash (SHA1) of queryString(base64 of the plaintext) and salt and entropy.
        4. 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

    1. Server side
      1. Compute the answer using database queries
      2. Retrieve salt from the database
      3. Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
      4. Compute hash (SHA1) of the answer(base64 of the plaintext), and salt, and entropy
      5. Post answer(base64 of the plaintext), and salt, and entropy, and the computed hash to the client
    2. Client side
      1. Read salt from user's machine
      2. Create an entropy in memory (base64 of a temporal value e.g. [hour of the day]+[day of the year])
      3. Split the received message to 4 parts: answer(base64 of the paintext); salt; entropy; 'received hash'
      4. Check if entropy matches (e.g. with base64 of [hour of the day]+[day of the year]) .
      5. Compute hash (SHA1) of answer(base64 of the plaintext) and salt and entropy.
      6. 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


    Solution

    1. The solution is to use HTTPS withTLS 1.2 and pin the certificate, there are certificate solutions that are free.

    2. Using a hash (SHA1 in this case) to protect a password has not been good secure practice for some time. For my reference see DRAFT NIST Special Publication 800-63B Digital Authentication Guideline.

    3. Passwords must be protected with an iterated HMAC, not a single hash. For more information on passwords see Toward Better Password Requirements by Jim Fenton, see slide 23 in particular. This seems to be at odds with the Pluralsight training, best practices have changes over time.