Client side hashing and encryption

Hashing and encryption is now available within browsers through javascript.

Why hash and encrypt on the client side?

Whenever you save a password on your server you should hash that password with salt.
This is great but the raw users password hits your servers before you get to hash it. With the recent revelations about the NSA fiber splitting content from the net (and asking for the SSL keys), it does means that this password could be unsecure.
By hashing the password on the client side, your server will never know the raw password and only see the hashed value. This raw password would never be sent on the internet lines so any middle man attacks would never know the true password.
You should still hash the password again on the server side before saving it anywhere in a database.
Read my previous post on how to do this: http://glynrob.com/php/hashing-and-public-key-encryption/

What if you wanted to offer a service where all user data is stored encrypted. Offering the encryption to take place on the client side gives them more security.
They can see that the real data they save is never sent to you, only in encrypted form and the password used to decrypt it is never on your server or shared with anyone.
If the NSA or any agency/hacker asks you to decrypt the data on your service, it would be impossible for you to do so.
If your user forgets his password, then they are out of luck as you can not set a new password for his content to be decrypted.
TNO = Trust NoOne

How to I Hash and Encrypt on the Client side?

WebCryptoAPI:
http://www.w3.org/TR/WebCryptoAPI/
A JavaScript API for performing basic cryptographic operations in web applications, such as hashing, signature generation and verification, and encryption and decryption.
Perfect, this is what we need, BUT
It is not ready. It is still being worked on so we can not use this until it is completed.

So instead I try these 3 libraries:

I recommend Crypto-JS as it is the easiest to use for hashing and encryption

Working example of my code can be found at: http://glynrob.com/examples/client-encryption/

Full code to download is available at: https://github.com/glynrob/client-encryption

Hash

As you can see, PolyCrypt is the more complex one to generate and CryptoJS is the easiest.
Also PolyCrypt doesn’t generate the same hash even though all of them are using SHA-256. This wouldn’t be a problem if you always stayed on PolyCrypt but if you ever change libraries then all previous passwords would fail.
I would recommend not using PolyCrypt due to this reason.

My example shows:

hash

Sending this hashed value instead of the users password is now a secure way to validate a user accessing your system.

Encryption

Due to ruling out PolyCrypt earlier I won’t go into its encryption but it is available on github.
CryptoJS provides the quickest results I have found.

encrypt

Now sending the encrypted string to the server means that you never know the data that you are storing, and it can only every be decrypted by the password set by the user.

If you know of any better libraries or implementations, feel free to add them below.

4 comments for “Client side hashing and encryption

  1. Anonymous
    November 29, 2013 at 11:26 pm

    Should salt be used for client side hashing as well?

  2. GlynRob
    December 3, 2013 at 4:30 pm

    Salt could be used for client side hashing, but offers no additional security.
    The salt would need to be sent to the server so it can be provided back to the user to generate the same hash. A middle man attack would see the salt in the clear so I don’t think it is worth adding in.
    For client side I would say use hashing for authentication, and encryption for all data.
    Therefore a middleman attack could get the encrypted content, but not decrypt it without the password (which was never shared with the server or anyone else).

  3. June 14, 2015 at 5:16 pm

    Thanks for a concise and simple explanation of Client side hashing and encryption.

    As an User Experience Architect building front-end interactive prototypes I don’t code complex UI’s. However, I was asked by a client to mock-up a working Login/Logout workflow and so this blog together with your examples on github has helped solidify things in my mind and allowed me to experiment.

    Much appreciated.

  4. Sergi
    March 1, 2019 at 6:13 am

    I’ve arrived here searching who has run the next idea i had today to login on my CMS:

    1- the server has stored (and encrypted) the password of the user in the database
    3- on the login form the user type her password
    4- the submitted form DON’T INCLUDE the password but a random string (16 chars) and a HASH OF THIS 16-STRING CONCATENATED WITH PASSWORD
    6- the server do the same hash operation with stored password on database and the 16-chars-string received and verify if it match with the sent with the form

    It’s so easy… so i’m answering why did it not be implemented it yet as standard. I think that the background idea is a little similar to private/public key mixed with 2FA. The private key is the password, and the authentication succeed only when the hashed sum match on both sides (bizarre public key? hehehe).

    I’ve had this idea just this week working on implement a 2FA login system using TOTPs (you know: temporal passwords of 6 digits generated using a secret key at both sides: client vs. server).

    So i think that this idea could be appliable very easily to a “simple” user/password system, instead to send always the raw user & password from client to server. As you said: i’ve not very much trust on the SSL invulnerability.

    TNO = Trust NoOne 😉

    Cheers!
    Sergi

Leave a Reply

Your email address will not be published. Required fields are marked *