Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

165
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda