Home > Enterprise >  Using openssl_decrypt() not displaying anything when trying to decrypted an encrypted data
Using openssl_decrypt() not displaying anything when trying to decrypted an encrypted data

Time:12-26

I am trying to decrypt data coming from ionic in PHP but it is not decrypting using openssl_decrypt().

In my ionic app, I was able to encrypt and also test the decryption function which works well. Below are both the encryption and decryption functions:

Encryption

encrypt(key, iv, value){
    const encrypted = CryptoJS.AES.encrypt(value, key, { iv: iv });

    const encryptedMessage = encrypted.toString();
    return encryptedMessage;
   }

Decryption

 decrypt(value, keys, ivs){
    const decryptedMessage = CryptoJS.AES.decrypt(value, keys, { iv: ivs 
  }).toString(CryptoJS.enc.Utf8);

   return decryptedMessage;
  }

Encrypted data with key and iv

$iv = "048eb25d7a45ff00";
$key = "feda4f2f67e7aa96";
$encrypted = "U2FsdGVkX1 kBV6Q5BQrjuOdi4WLiu4 QAnDIkzJYv5ATTkiiPVX8VcDUpMqSeIwCfyTNQOosp/9nYDY4Suu4/Lmhh2quKBU7BHGOtKwu9o=";

**To decrypt in PHP**

<?php

    // Use openssl_decrypt() function to decrypt the data
    $output = openssl_decrypt($encrypted, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
    echo $output;

?>

How can I decrypt this?

CodePudding user response:

In the CryptoJS code, the key material is passed as string, which is why it is interpreted as password and a key derivation is applied. The key derivation function used is the OpenSSL proprietary EVP_BytesToKey(). During encryption, CryptoJS.AES.encrypt() does the following:

  • Generate an 8 bytes salt implicitly.
  • Derive a 32 bytes key and 16 bytes IV based on the salt and password using EVP_BytesToKey().
  • Encrypt the plaintext with key and IV, ignoring any explicitly passed IV (here 048eb25d7a45ff00)!
  • Convert the data to OpenSSL format (by encrypted.toString()): Base64 encoding of the ASCII encoding of Salted__, followed by the 8 bytes salt and the actual ciphertext.

Therefore, decryption must be carried out as follows:

  • Separate salt and actual ciphertext.
  • Derive the 32 bytes key and 16 bytes IV from salt and password using EVP_BytesToKey(). Note that the IV 048eb25d7a45ff00 is not needed.
  • Decrypt the ciphertext with key and IV.

A possible implementation:

// Separate salt and actual ciphertext
$saltCiphertext = base64_decode("U2FsdGVkX1 kBV6Q5BQrjuOdi4WLiu4 QAnDIkzJYv5ATTkiiPVX8VcDUpMqSeIwCfyTNQOosp/9nYDY4Suu4/Lmhh2quKBU7BHGOtKwu9o=");
$salt = substr($saltCiphertext, 8, 8);
$ciphertext = substr($saltCiphertext, 16);

// Separate key and IV
$keyIv = EVP_BytesToKey($salt, "feda4f2f67e7aa96");
$key = substr($keyIv, 0, 32);
$iv = substr($keyIv, 32, 16);

// Decrypt using key and IV
$decrypted = openssl_decrypt($ciphertext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
print($decrypted . PHP_EOL); // {"username":"07069605705","password":"father2242"}

// KDF EVP_BytesToKey()
function EVP_BytesToKey($salt, $password) {
    $bytes = ''; $last = '';
    while(strlen($bytes) < 48) {
        $last = hash('md5', $last . $password . $salt, true);
        $bytes.= $last;
    }
    return $bytes;
}

Note: EVP_BytesToKey() is deemed insecure nowadays and should not be used. A more secure alternative is PBKDF2 which is supported by both CryptoJS and PHP.

  • Related