Message Encryption in JavaScript and PHP

Message Encryption in JavaScript and PHP

Just for fun, let's encrypt some stuff in client-side JavaScript and have a PHP server decrypt it. Note that **this [will never replace TLS (HTTPS)](https://stackoverflow.com/a/12327375/2224584)**. ## JavaScript Encryption with...

Just for fun, let's encrypt some stuff in client-side JavaScript and have a PHP server decrypt it. Note that this will never replace TLS (HTTPS).

JavaScript Encryption with Sodium-Plus

You'll want the latest release of sodium-plus for this. (As of this writing, it's version 0.4.0.)

<script
  src="/static/js/sodium-plus.min.js"
  integrity="sha384-lv7SVE0eb0bXA3fgK6PwlhViiUwG6tBuMAhS8XX7RvBvyRcdEdJ8HKtFgs4vHTUh"
></script>

Next, you'll want to write some JavaScript code to encrypt a message and send it to a server. I'll be using jQuery for this example, but you can easily adapt it to use a XMLHttpRequest object instead.

Let's define two functions. One loads a CryptographyKey object from a hard-coded string (n.b. you never want to actually do this, but for the sake of an easy, working example, we're using a hard-coded secret). The other actually encrypts a message.

/**
 * Get the example key. In the real world, you want to generate these randomly.
 */
async function getExampleKey() {
    if (!window.sodium) window.sodium = await SodiumPlus.auto();
    return CryptographyKey.from(
        'e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0',
        'hex'
    );
    // return await sodium.crypto_secretbox_keygen();
}

/**
 * Encrypt a message under a given key.
 */
async function encryptMessage(message, key) {
    if (!window.sodium) window.sodium = await SodiumPlus.auto();

    let nonce = await sodium.randombytes_buf(24);
    let encrypted = await sodium.crypto_secretbox(message, nonce, key);
    return nonce.toString('hex') + encrypted.toString('hex');
}

Next, you'll want to write a function that gathers user input, encrypts it, and sends it to a server.

async function sendEncryptedMessage() {
    let key = await getExampleKey();
    let message = $("#user-input").val();
    let encrypted = await encryptMessage(message, key);
    $.post("/send-message", {"message": encrypted}, function (response) {
        console.log(response);
        $("#output").append("<li><pre>" + response.message + "</pre></li>");
    });
}

...and some supporting HTML:

<label for="user-input">Type a message to encrypt and send:</label>
<textarea id="user-input"></textarea>
<button id="send-it" type="button">Send Encrypted Message</button>
<hr />
<ol id="output"></ol>

<script type="text/javascript">
$("#send-it").on('click', sendEncryptedMessage);
</script>

PHP Decryption with Sodium

You're going to want paragonie/sodium_compat.

If you're using PHP 7.2, with overwhelming probability you can just use the built in sodium_* functions. However, some distros may incorrectly disable the sodium extension by default. So to play it safe, install sodium_compat anyway.

If you're using a framework (Symfony, Laravel), your code will look a lot cleaner, but for the sake of illustration, the decryption code will look like this:

<?php
declare(strict_types=1);

require 'vendor/autoload.php'; // Composer

header('Content-Type: application/json');

$key = sodium_hex2bin('e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0');

$encrypted = $_POST['message'] ?? null;
if (!$encrypted) {
    echo json_encode(
        ['message' => null, 'error' => 'no message provided'],
        JSON_PRETTY_PRINT
    );
    exit(1);
}

$nonce = sodium_hex2bin(substr($encrypted, 0, 48));
$ciphertext = sodium_hex2bin(substr($encrypted, 48));
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

echo json_encode(
    ['message' => $plaintext, 'original' => $encrypted],
    JSON_PRETTY_PRINT
);

Putting it Together

When you type in a message and press the button, it will encrypt it and send a hex-encoded string to the server.

The PHP code will then decrypt the message and return the plaintext in a JSON response.

The JavaScript code will then grab the plaintext from the JSON response and append it to the output field below the form.

Security Considerations

This is just a toy example to illustrate how to use sodium-plus (JavaScript) and libsodium (PHP) to encrypt/decrypt messages.

We took a lot of shortcuts that you won't want to take in a real system (for example: hard-coding the encryption keys, and eschewing error-checking in favor of brevity).

javascript php

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

PHP json_decode Example | Decode JSON Data in PHP Tutorial

PHP json_decode is an inbuilt function that takes the JSON encoded string and converts it into a PHP variable. JSON stands for JavaScript Object Notation.

Hire PHP Developer

Looking to develop a PHP based website from scratch or revamp your existing website? **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")** has always been an industry leader for companies and business owners looking to hire...

Hire Dedicated PHP Developer

Looking to hire affordable yet experienced PHP developers? **[Hire Dedicated PHP Developer](https://hourlydeveloper.io/hire-dedicated-php-developer/ "Hire Dedicated PHP Developer")**, who can convert your idea to reality, within the stipulated...

The essential JavaScript concepts that you should understand

The essential JavaScript concepts that you should understand - For successful developing and to pass a work interview

Country State City Dropdown list in PHP MySQL PHP

Country state city dropdown using ajax in php. You'll learn how to populate country city state dropdown based on previous selection in php using ajax