Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

171
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda