Search code examples
javascriptencryptioncryptojs

What's the best option using cryptojs, have the key stored in client and server sides, or generate the key and pass it some way to the other side?


I want to encrypt and decrypt the data passed between the client and the server using cryptojs. To decrypt the data it is necessary to know the key used, so Imhave two options:

  • Use a fixed key stored in both sides.
  • Generate randomly the key and pass it to the other side with the data.

In both cases, if the petition is captured, you can resend it to the server and access to the page.

If I use a fixed key, if you get the key, you can decrypt all the messages, except if you change the key.

If I pass the key with the data, you get the key with the data (I pass in a no clear way, so you have to know what part is the key and what part is the data). But this key changes with every petition.

Anyway, I think the attacker could just see the client side code and discover the procedure used to encrypt the data and do the opposite procedure.

What's the best option?

PD: I know that https is the way, but I want tp do this too.


Solution

  • Option: 1

    Assuming that you want to use CryptoJS and you want to use HTTP, and you don't want the attacker to know the secret key, you can use PBKDF2.

    PBKDF2 is a password-based key derivation function

    You can generate a key from the user's password on browser and use it to encrypt the data encryption key.

    On server side, assuming that you will have access to user's password from the user database, you can re-generate the same PBDKF2 key using the password and decrypt the data encryption key.

    Once both server and client have agreed on a shared data encryption key, they can have future exchange of data using that key. In this process, a hacker may not get access to the data encryption key as it was exchanged in encrypted form. Also, it requires a human to enter a password whose value hacker is not aware of.

    NOTE 1: This solution will not work if you are authenticating user against third party authentication provider and you do not have access to user's password.

    NOTE 2: CryptoJS seems to support only symmetric ciphers - hence, there will be a need to exchange key between client and server. The key has to be exchanged via a shared secret that is not shared using the same channel on which key will be used.

    Option: 2

    If you cant use PBDKF2 for some reason, and still want to exchange keys securely between client and server, then, you will have to employ asymmetric encryption. A library JSEncrypt provides RSA encryption.

    If this library is employed, then, client (browser) can generate a key usng CryptoJS and encrypt it with a RSA public key using JSEncrypt and send the encrypted key to server. Server can decrypt the encrypted-key using RSA private key. This process will result in safe exchange of key.