When attempting to decrypt with a password using CryptoJS, AES decryption returns an empty result

Example

The code snippet below is what I am currently using:

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"><input type="button" id="enc_button" value="Save">
<script>
    var password = "testpassword";
    var encrypted_text = localStorage.getItem("encrypted");
    var rawData = atob(encrypted_text);
    var iv = rawData.substring(0,16);
    var crypttext = rawData.substring(16);
    var plaintextArray = CryptoJS.AES.decrypt(
      { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) },
      CryptoJS.enc.Hex.parse(password),
      { iv: CryptoJS.enc.Latin1.parse(iv) }
    );
    var decrypted = CryptoJS.enc.Latin1.stringify(plaintextArray);
    document.getElementById("decrypted").innerHTML = decrypted;
    document.getElementById("enc_button").onclick = function(){
    var text = document.getElementById("new_note").value;
    var encrypted = CryptoJS.AES.encrypt(text, password);
    localStorage.setItem("encrypted",encrypted);
    }
</script>

Intended Functionality

The goal is to encrypt a string with AES using CryptoJS and then decrypt the saved encrypted text from local storage to display the result in a div.

Current Issue

Although the string appears to be encrypted successfully, the variable decrypt remains empty. No errors are being logged in the Chrome console.

Inquiry

How can I ensure successful encryption and decryption of my text?

Answer №1

CryptoJS offers two variations of encryption and decryption methods.

When utilizing

var encrypted = CryptoJS.AES.encrypt(text, password);

you are engaging in password-based encryption as opposed to traditional key/IV-based encryption. Essentially, this method involves running the password and a randomly generated salt through an MD5 invocation to generate the key and IV for encryption purposes. The resulting encrypted object retains the salt used to derive the key and IV.

If you convert encrypted into a string (e.g., storing it in localStorage), it transforms into an OpenSSL compatible string encoding that includes the salt. To decrypt it, there is no need to handle the key, IV, or salt manually; CryptoJS handles this process automatically:

var decrypted = CryptoJS.AES.decrypt(encrypted, password);

Note that decrypted is represented as a WordArray object, which converts to Hex by default when turned into a string. To specify another encoding like UTF-8, you must define it explicitly.

If decryption fails due to factors like an incorrect key, ciphertext, or encoding, CryptoJS typically returns a blank value instead of throwing custom error messages. The library assumes users understand the intricacies of their actions.

Here is the full code snippet:

var password = "testpassword";

document.getElementById("enc_button").onclick = function(){
  var text = document.getElementById("new_note").value;
  
  var encrypted = CryptoJS.AES.encrypt(text, password);
  encrypted = encrypted.toString();
  
  var decrypted = CryptoJS.AES.decrypt(encrypted, password);
  decrypted = decrypted.toString(CryptoJS.enc.Utf8)
  
  document.getElementById("decrypted").innerHTML = decrypted;
}
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"><input type="button" id="enc_button" value="Encrypt & Decrypt">

Answer №2

While trying to troubleshoot your code, I discovered that the script was placed in a try-catch block and it seems like document.getElementById is returning undefined. This is likely due to the method being called before the element is created. To resolve this issue, follow these steps:

Head:

var password = "securepassword";
var encrypted_text = localStorage.getItem("encrypted_data");
var rawData = atob(encrypted_text);
var iv = rawData.substring(0, 16);
var crypttext = rawData.substring(16);
var plaintextArray = CryptoJS.AES.decrypt(
    { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) },
    CryptoJS.enc.Hex.parse(password),
    { iv: CryptoJS.enc.Latin1.parse(iv) }
);
var decryptedData = CryptoJS.enc.Latin1.stringify(plaintextArray);

function setComponents() {
    try {
        document.getElementById("decrypted_content").innerHTML = decryptedData;
        document.getElementById("encryption_button").onclick = function(){
            var inputText = document.getElementById("new_note_input").value;
            var encryptedMessage = CryptoJS.AES.encrypt(inputText, password);
            localStorage.setItem("encrypted_data", encryptedMessage);
            alert(encryptedMessage);
        };
    } catch(error) {
        alert(error);
    }
}

Body:

<body onload="setComponents()">
<div id="decrypted_content">Please wait...</div>
Insert new note:<input type="text" id="new_note_input"/><input type="button" id="encryption_button" value="Save"/>
</body>

Answer №3

If you're struggling with API development, double check the contents of your request body to ensure that all object properties are correctly named! It might seem simple, but it can save you hours of frustration.

Answer №4

If you want to see examples, just take a look at the source code.
The simplest way to generate key, iv, and salt from a passphrase is using CryptoJS.AES.encrypt("attack at dawn!","passphrase")
You can also set parameters upfront like this:

CryptoJS.algo.AES.keySize=32
CryptoJS.algo.AES.blockSize=8
CryptoJS.algo.AES.ivSize=16
CryptoJS.algo.EvpKDF.cfg.iterations=100
CryptoJS.algo.EvpKDF.cfg.keySize=32

and so on.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

PHP: Link to logo in different folder by including 'nav.php'

I am facing an issue with my nav.php file: <div> <!-- there's a lot of code here so I want to write it once and include it in all pages within the main folder as well as subfolders <img src="logo.png"> </div> The structur ...

"Excessive use of Javascript setInterval combined with frequent ajax calls is causing significant

I have integrated the setInterval() function into my JavaScript code to make an AJAX call every 2 minutes. However, I noticed that this is causing the website to slow down over time. The website is built using Node.js. After doing some research, I came acr ...

Tips for integrating Chart.js into my AngularJS application?

I am a beginner with AngularJS and I'm currently developing an application on Ubuntu. While trying to add Chart.js using npm install chart.js, an error is being displayed as follows. npm WARN <a href="/cdn-cgi/l/email-protection" class="__cf_emai ...

Do not attempt to log after tests have finished. Could it be that you overlooked waiting for an asynchronous task in your test?

Currently, I am utilizing jest in conjunction with the Vue framework to create unit tests. My test example is successfully passing, however, I am encountering an issue with logging the request. How can I resolve this error? Is there a mistake in my usage o ...

Node.js Express API returns an error status with an empty array response in a RestFul manner

Currently, I am in the process of developing a RestFull API using Node.JS to validate if a specific license plate is registered in my database (which happens to be MySQL). The endpoint that I have set up for this task is as follows: http://localhost:3009/_ ...

Unable to connect beyond the local network using Socket.io

server.js import { Server } from "socket.io"; const io = new Server(8000); io.on("connect", (socket) => { console.log(`connect ${socket.id}`); socket.on("ping", (cb) => { console.log("ping"); ...

Tips on modifying a Vue app's property externallyHere are some techniques on how

I am curious about changing the property of a vue app from an external source. I want to create a new vue app named 'app' and set 'app.propertyName' to 'someValue'. However, my attempt below did not yield the desired outcome. ...

Positioning the filters in jQuery Datatables

I'm currently working with jQuery datatables and I'm attempting to align the filter/search box on the same row as the header of the container holding the datatable. Attached is a screenshot for reference: https://i.stack.imgur.com/nzbIl.png He ...

Guide on producing a milky overlay using Vue js

Currently, I am utilizing Vue 3 along with Bootstrap 5 in my project. In my application, there is a button and two input fields. Upon clicking the button, I would like to display a "milky" overlay as shown in this example: https://i.sstatic.net/K21k8.png ...

What is the best way to save and access multiple arrays within a single object in local storage?

I am looking to streamline my code by combining 5 arrays into a single object and storing it in local storage. However, when trying to retrieve the object later on, the properties are showing up as undefined. To address this issue, I want to push an object ...

ImageMapster for perfect alignment

I'm struggling with centering a div that contains an image using imagemapster. When I remove the JS code, the div centers perfectly fine, indicating that the issue lies with the image mapster implementation. It's a simple setup: <div class=" ...

Selenium Refuses to Launch My Local Browser Despite Explicit Instructions

While using Chrome browser with selenium, I encountered an issue related to browser profiles. Everything works smoothly when the correct binary path is provided, but if an incorrect path is given, it refuses to run. The specific problem arises when the br ...

Use Javascript to set cookies and remember the show state when clicked

Can you offer some advice? I am looking to add cookies to my simple JavaScript code. Currently, the div is displayed when clicking on a link, but it hides again when the page reloads. I would like to implement cookies to remember the show state for 7 days. ...

What is the best way to run code once a callback function has completed its task?

I am looking for a way to execute line(s) of code after every callback function has finished processing. Currently, I am utilizing the rcon package to send a rcon command to a Half-Life Dedicated Server (HLDS) hosting Counter Strike 1.6 server and receive ...

Wait to display the page until all AngularJS directives have finished loading their HTML content

I've encountered an issue in my AngularJS application where I created directives that load external HTML templates from another URL. The problem is that when I navigate to the page, the binding works fine but the directive's HTML doesn't loa ...

The Express Electron framework does not support importing local JavaScript files

Despite my extensive search before flagging this as a duplicate, I have not been able to find the solution I need. I am encountering issues with using express and electron. Everything runs smoothly when I execute npm start (the start script in package.jso ...

Resolving the Table Issue with 'onclick' in Javascript

Apologies for the lack of creativity in the title, I struggled to come up with something fitting. Currently, I am engaged in the development of a user-friendly WYSIWYG site builder. However, I have encountered an obstacle along the way. I've devised ...

What is the process for uploading an HTML input file in segments?

Is it possible to upload the whole file at once like this: myInput.onchange = ({ target }) => { const file = target.files[0]; const formData = new FormData(); formData.append("fileData", file); // ...then I post "formData" ...

Arranging an array of arrays based on the mm/dd/yyyy date field

Currently, I am facing an issue while attempting to sort data obtained from an API by date in the client-side view. Here is an example of the data being received: address: "1212 Test Ave" address2: "" checkNumber : "" city: "La Grange" country: "" email: ...

Image remains fluid within a static div without resizing

Any assistance would be greatly appreciated. I am currently facing an issue with a fixed div that is floating at the bottom of the screen, serving as ad space for the mobile version of a website. The problem arises when attempting to resize the browser win ...