DEV Community

Cover image for Secure Web applications using CryptoJS and PHP
Deepak Singh
Deepak Singh

Posted on

Secure Web applications using CryptoJS and PHP

Encrypt data using JS on front end and decrypt using PHP on backend using AES encryption method.

Why to use this method
To prevent Man-in-the-middle (MITM) attacks. Maximum cyber attacks occur MITM attacks. It means the attacker can be seen (intercept) your data before the server receives it from your browser. What if the data we send is already encrypted on the browser itself and sent to the server. It is where the crypto-to-php method works.

How to use it
Just encrypt the data using the method below:

CryptoJS.AES.encrypt(JSON.stringify(dataValue), TheSecret, {format: CryptoJSAesJson}).toString();
Enter fullscreen mode Exit fullscreen mode

dataValue is your input value the TheSecret is your secret key. You can use your custom random generated secret key, I have used time() for demo purposes. You can use PHP Encryption Methos for your custom secret key encryption and decryption.

The method I used to achieve the purpose (just for demo purposes).
Start with data encryption on Front-End

var dt = new Date();
var TheSecret = "";
$(document).ready(function(e) {
    $.ajax({
        url:'libs/php/get_random_key.php',
        type:'POST',
        data:"dts="+dt.getTime(),
        success: function(responseAjx){
            TheSecret = responseAjx;
            console.log(TheSecret);
        }
    });
});
$('button[name="sub"]').click(function(e) {
    var dataValue = $('input[name="data"]').val();
    var enData = CryptoJS.AES.encrypt(JSON.stringify(dataValue), TheSecret, {format: CryptoJSAesJson}).toString();
    $.ajax({
        url:'libs/php/decrypt.php',
        type:'POST',
        data:'crypt='+enData,
        success: function(cryptResponse){
            console.log(cryptResponse);
        }
    });

});
Enter fullscreen mode Exit fullscreen mode

Here is the JS Encryption and Decryption Library CryptoJS & Method

Here is the get_random_key.php code:

session_start();
$sname = time();
$_SESSION['cryptPs'] = $sname;
echo $sname;
Enter fullscreen mode Exit fullscreen mode

Here is the decrypt.php code:

session_start();
$key = $_SESSION['cryptPs'];
include('aes-encryption.php');
if(isset($_POST)){
    echo cryptoJsAesDecrypt($key, $_POST["crypt"]);
}
Enter fullscreen mode Exit fullscreen mode

Find the aes-encryption.php here PHP AES Encryption

Find details code here GitHub

Discussion (1)

Collapse
inkeliz profile image
Inkeliz • Edited on

I don't that article makes any sense.

First, you are using symmetrical-keys and those keys are being shared in the same channel, so you end with zero-protection against MITM. The only way to that work is sharing keys "out-of-band". Otherwise, what prevents the attacker to change (or see) the key when you request libs/php/get_random_key.php?

If the purpose of the AES is to share data between two parties, you need some "key agreement" in another channel of communication or you should use a key-exchange such as ECDH. But even using ECDH (or equivalente key exchange): you must somehow key-pinning/trust the server-key, or you must also have another trusted signature key (say Ed25519) that signs the ephemeral ECDH key...

However, the TLS/SSL already does it for you. So, if you use TLS you already have protection against MITM, you don't need to use CryptoJS anymore for that.

The CryptoJS can be used to encryption, but not even close of how it was described in this article. The example using time is awful, I don't need to say why. A better valid example would be using PBKDF2 to create a AES-key using some password to encrypt a file, that the server can't read the content and can only be decrypted by the user. Or, maybe using the PBKDF2 to create a X25519 key and exchange a key with the trusted-server-key (which can be done without request) and send the data encrypted, but I think CryptoJS doesn't handle it, so maybe Libsodium would be a better choice.