These JS and Perl scripts may encrypt the same data, but they generate different results. Isn't it expected for them to produce identical output?

Two different programs, one in Javascript and the other in Perl, were designed to accomplish the same task with identical input data. Nevertheless, the output generated by these programs varied. The issue stemmed from using JavaScript on the client side to send a POST request to a Perl app on the server side, causing failure in decrypting the data without any clear explanation. Upon closer inspection, I determined that the libraries used in the two distinct programming languages exhibited different behaviors. To validate this observation, I rewrote the client side code in Perl. The outcomes are outlined below.

const CryptoJS = require('crypto-js');

function logBytes(description, wordArray) {
    const bytes = CryptoJS.enc.Hex.stringify(wordArray);
    console.log(description, bytes);
}

function encrypt(key32, iv16, data) {
    // Remaining JavaScript encryption logic...
}

const data = "myemail@myserver.com";
// key32 and iv16 declarations...

encrypt(key32, iv16, data);

output:

% node test.js
Data: myemail@myserver.com
Key Bytes: 9d066ab6dc74593bbcef0876b4f7c00bada3acce6134fc64fa31a2cf995a39dd
IV Bytes: 9b2b9bdb4af5357cd78a8a2257c51a7f
Data Bytes: 6d79656d61696c406d797365727665722e636f6d
Encrypted (Base64): iit+mjBnWsMrMkJp63hpRmsCZgIxZ4FPZQId35qv12s=
#!/usr/bin/perl

use strict;
use warnings;

sub logMessage {
  # Perl logMessage function implementation...
}

sub logBytes {
    # Implementation for logging bytes in Perl...
}

sub encrypt {
    # Remaining Perl encryption logic...
}

sub main {
  # Main method definition for Perl program...
}

main();
exit (0);

output

% ./test.pm  
Data: myemail@myserver.com
Key Bytes: 9d066ab6dc74593bbcef0876b4f7c00bada3acce6134fc64fa31a2cf995a39dd
IV Bytes: 9b2b9bdb4af5357cd78a8a2257c51a7f
Data Bytes: 6d79656d61696c406d797365727665722e636f6d
Encrypted (Base64): rk7JgOwsb7atyvEIXVNQkexbx5SYzufE05LZAoqtZGk=
Versions:

Perl:
Crypt::OpenSSL::AES version: 0.19
MIME::Base64 version: 3.16

JS:
JavaScript library versions listed here 

Answer №1

Thanks to the invaluable help of @Topaco for providing the crucial clue - all credit goes to him.

Below is a solution that combines client-side JS and server-side Perl:

const CryptoJS = require('crypto-js');

function encryptData(key_hex, iv_hex, data) {
    const key = CryptoJS.enc.Hex.parse(key_hex);
    const iv = CryptoJS.enc.Hex.parse(iv_hex);
    const utf8data = CryptoJS.enc.Utf8.parse(data);

    const encrypted = CryptoJS.AES.encrypt(utf8data, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

    // Convert to base64 for easier transmission and compatibility with Perl's decode_base64
    return encrypted.toString();
}

var key_hex = "9d066ab6dc74593bbcef0876b4f7c00bada3acce6134fc64fa31a2cf995a39dd";
var iv_hex  = "9b2b9bdb4af5357cd78a8a2257c51a7f";
var data    = process.argv[2];
const encryptedBase64 = encryptData(key_hex, iv_hex, data);
console.log(encryptedBase64);
use MIME::Base64;
use Crypt::CBC;

use strict;

sub decryptHex {
  my ($key_hex, $iv_hex, $data) = @_;
 
  # Convert hexadecimal key and IV to binary format
  my $key = pack("H*", $key_hex);
  my $iv = pack("H*", $iv_hex);

  # Set up decryption cipher with CBC mode and Rijndael (AES)
  my $cipher = Crypt::CBC->new(
        -key    => $key,
        -cipher => 'Crypt::Rijndael',
        -iv     => $iv,
        -header => 'none',
        -keysize => 32,  # Adjust based on key length (16 for AES-128, 24 for AES-192, 32 for AES-256)
        -literal_key => 1,
        -padding => 'standard'  # Handles PKCS#7 padding
  );

  # Decode base64-encoded data
  my $encrypted = decode_base64($data);

  # Decrypt the data
  my $decrypted = $cipher->decrypt($encrypted);

  return $decrypted;
}

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

Utilizing jQuery to update dropdown selection based on JSON object values

In my JSON value, I have the following roles: var roles = { "roles":[ {"role_id":2,"role_name":"admin"}, {"role_id":4,"role_name":"QA"}, {"role_id":3,"role_name":"TL"}, {"role_id":5,"role_name":"user"}, {"role_id":1,"role_name":"r ...

Using canvas to smoothly transition an object from one point to another along a curved path

As a beginner in working with canvas, I am facing a challenge of moving an object from one fixed coordinate to another using an arc. While referring to the code example of a solar system on https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutori ...

"Exploring the world of asynchronous computations in jQuery Ajax: The next steps post-GET

When using ajax in jQuery with the request type, URL, and success functions, I often receive a JSON response. However, I face the challenge of needing to reformat the JSON arrays into a different structure, which can be computationally expensive. I am seek ...

What is the best way to incorporate Form Projection into Angular?

I have been attempting to incorporate form projection in Angular, inspired by Kara Erickson's presentation at Angular Connect in 2017, but I am encountering difficulties and errors along the way. view talk here The code provided in the slides is inco ...

Is JavaScript responsible for creating threads for non-blocking AJAX requests?

It is widely believed that JavaScript operates on a single-threaded model, but it has the ability to run asynchronously. One intriguing aspect is how this single-threaded model manages non-blocking AJAX requests. Consider a scenario where a non-blocking A ...

Unleashing a cascade of infinite promises

When it comes to handling an expensive computation within a function that is called frequently and needs to return quickly, my approach involves chaining promises together with this. This method seems to be effective in ensuring that computations occur seq ...

The AudioPlayer refuses to play following a track change

I am looking to implement an audio player in React Nextjs that features interactive dots, each representing an audio track. The functionality I want is such that clicking on a dot will pause the currently playing track (if any) and start playing the select ...

Detect Flash Player Event using Javascript

Is there a way to detect when a flash video ends without depending on user input like clicking the stop button? It's important to note: I HAVE NO CONTROL OVER THE PRESENTATIONS OR SWF FILES. My goal is to automate the client player object through s ...

Guide to verify the user selection within a select form

Here is a form with a select field: <form method="post" name="posting_txt" onSubmit="return blank_post_check();" id="post_txt"> <select style="background: transparent; border-bottom:5px;" name="subname" class="required"> ...

Ajax fails to transmit information

Currently, I am in the process of familiarizing myself with the usage of ajax. An issue that I am encountering is that clicking a submit button in a form does not effectively send data. Below you can find the JQuery code I am using: $('input[name=" ...

Error encountered: The JSONP request to https://admin.typeform.com/app/embed/ID?jsoncallback=? was unsuccessful

I encountered an issue with the following error message: Error: JSONP request to https://admin.typeform.com/app/embed/id?jsoncallback=? Failed while trying to integrate a typeform into my next.js application. To embed the form, I am utilizing the react-ty ...

tips for effectively coordinating functions with promises in node.js

Hey there! I'm currently working on synchronizing my functions by converting callbacks to promises. My goal is to add the post.authorName field to all posts using a forEach loop and querying the user collection. Initially, I attempted to use callb ...

Comparing react-intl and react-i18next for internationalizing ReactJS applications

I am in the process of developing a multilanguage application using ReactJS. This application will require a custom dictionary for various languages, as well as automatic formatting for date/time, numbers, and currency. After researching, I have come acro ...

Understanding how flex-wrap property works in flexbox is essential for creating

Take a look at the code snippet below: .flex-container { padding: 20px; margin: 20px; list-style: none; border: 1px solid silver; -ms-box-orient: horizontal; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -moz- ...

Array containing two objects in a two-dimensional format

In the example provided, I am working with a 2D array. Link to the example: https://codesandbox.io/s/v0019po127 I am noticing different results depending on whether I use the browser console or Codesandbox's console. I have attempted using JSON.str ...

What is the process for extracting dates in JavaScript?

I need help extracting the proper date value from a long date string. Here is the initial date: Sun Aug 30 2020 00:00:00 GMT+0200 (Central European Summer Time) How can I parse this date to: 2020-08-30? Additionally, I have another scenario: Tue Aug 25 ...

Issues with Angular route links not functioning correctly when using an Array of objects

After hard coding some routerLinks into my application and witnessing smooth functionality, I decided to explore a different approach: View: <ul class="list navbar-nav"></ul> Ts.file public links = [ { name: "Home&quo ...

Establishing a link between numerous web browsers solely through client-side technology

After creating a compact AJAX-powered chat application, I wonder if it is feasible to handle all the communication client-side. Can individual pages recognize each other and share real-time updates without involving the server? Is there a way to achieve th ...

Comparing obj.hasOwnProperty(key) with directly accessing obj[key]

Consider the scenario where I need to determine if a property exists within an Object. A comparison between two methods caught my attention: if(object.hasOwnProperty(key)) { /* perform this action */ } OR if(object[key]) { /* perform this action */ ...

Exploring the world of Ajax and managing cookies

I am facing an issue with setting cookies in my login form using ajax when the "remember me" checkbox is checked. Despite having code to handle this scenario, the cookies are not getting set properly. After executing var_dump($_COOKIE), I see that only the ...