Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

163
Views
Getting substring of a CryptoJS's TripleDES encrypted string

I've a legacy php code that encrypts with TripleDES method as a part of a bank flow to encrypt purchase operations. This is the code:

/******  3DES Function  ******/
function encrypt_3DES($message, $key){
    $l = ceil(strlen($message) / 8) * 8;
    return substr(openssl_encrypt($message . str_repeat("\0", $l - strlen($message)), 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, "\0\0\0\0\0\0\0\0"), 0, $l);
}

I want to reproduce the same code in javascript using CriptoJS's TripleDES. This is my trial so far:

<script src=https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/tripledes.js></script>
<script>

    function encrypt_3DES(message, key) {
        // Parse input parameters
        message = CryptoJS.enc.Utf8.parse(message);
        key = CryptoJS.enc.Utf8.parse(key);
        // Build an iv with zero values
        let iv = CryptoJS.lib.WordArray.create(64/8);
        let encrypted = CryptoJS.TripleDES.encrypt(message, key, {iv: iv});
        // Encrypt with TripleDES
        return encrypted.toString();
    }

    let message = "testMessage";
    let key = "testKey";

    let encrypted = encrypt_3DES(message, key);
    // encrypted: "HLu4p18KtFfy5VjwjFkDHA=="
    
</script>

Taking the example values, the result is the string "HLu4p18KtFfy5VjwjFkDHA==".

The problem is that the results between js and php are slightly different, and my suspictions are pointing to the substr operation done on the php side, because when I'm converting the result of the open_ssl operation (without the substring), my javascript code is returning the same base64 string:

<?php

/******  3DES Function  ******/
function encrypt_3DES($message, $key)
{
    $l = ceil(strlen($message) / 8) * 8;
    return substr(openssl_encrypt($message . str_repeat("\0", $l - strlen($message)), 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, "\0\0\0\0\0\0\0\0"), 0, $l);
}

$message = "testMessage";
$key = "testKey";

$res = base64_encode(encrypt_3DES($message, $key));
$res2 = base64_encode(openssl_encrypt($message, 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, "\0\0\0\0\0\0\0\0"));

/* $res: HLu4p18KtFfTr47KvI/WEw== (My goal is to get this in javascript) */
/* $res2: HLu4p18KtFfy5VjwjFkDHA== (without the substr operation, the results match) */
?>

So, my question is: Is there a way to apply the same substring to the encrypted result of the javascript's CryptoJS operation?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

The PHP code implements a custom zero padding. However, the default PKCS#7 padding is not disabled, so in addition to the explicit zero padding, a full block is unnecessarily appended by the implicit PKCS#7 padding.
This last unnecessary block is removed using substr(). The bottom line is that simply zero padding is used.

A more efficient PHP implementation would be to just disable the default padding with OPENSSL_ZERO_PADDING instead of truncating the last block:

return openssl_encrypt($message . str_repeat("\0", $l - strlen($message)), 'des-ede3-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0"). 

Anyway, in order for the C# code to return the same ciphertext as the PHP code, the padding in the C# code needs to be changed to CryptoJS.pad.ZeroPadding.


Note that a static IV (like the zero IV used here) is insecure, TripleDES is slow (better: AES) and zero padding is unreliable (better: PKCS#7).
Also, valid key sizes for TripleDES are 24 bytes and 16 bytes.


Test:

The PHP code below:

$key = '012345678901234567890123';
$message = 'The quick brown fox jumps over the lazy dog';
print(base64_encode(encrypt_3DES($message, $key)) . PHP_EOL);

produces the following Base64 encoded ciphertext:

HNQad59lGkM83byQY2pwhluVkB7YOyIx/kGh/ibcIXQdFoiODkD1kTIIEHhqcoFm

The fixed JavaScript code gives the same ciphertext.

function encrypt_3DES(message, key) {
    // Parse input parameters
    message = CryptoJS.enc.Utf8.parse(message);
    key = CryptoJS.enc.Utf8.parse(key);
    // Build an iv with zero values
    let iv = CryptoJS.lib.WordArray.create(64/8);
    let encrypted = CryptoJS.TripleDES.encrypt(message, key, {iv: iv, padding: CryptoJS.pad.ZeroPadding});
    // Encrypt with TripleDES
    return encrypted.toString();
}

let message = "The quick brown fox jumps over the lazy dog";
let key = "012345678901234567890123";

let encrypted = encrypt_3DES(message, key);
document.getElementById("ct").innerHTML = encrypted;
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="ct"></p>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!