0

We replaced Mcrypt with OpenSSL for encrypting and decrypting passwords that are stored in a DB. These are the new functions we are using:

function encrypt_openssl_password($key, $pwd)
{
    $cipher="AES-256-CBC";
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes( $ivlen );
    $encrypted = base64_encode(
        $iv .
        openssl_encrypt(
          $pwd,
          $cipher,
          hash('sha256', $key, true),
          OPENSSL_RAW_DATA,
          $iv
        )
    );
    return $encrypted;
}
function decrypt_openssl_password($key, $str)
{
    $data = base64_decode($str);
    $cipher="AES-256-CBC";
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = substr($data, 0, $ivlen);
    $decrypted = rtrim(
      openssl_decrypt(
        base64_encode(substr($data, $ivlen)),
        $cipher,
        hash('sha256', $key, true),
        OPENSSL_ZERO_PADDING,
        $iv),
      "\0"
    );
    return $decrypted;
}

The problem:

When we decrypt an old password (that was encrypted with Mcrypt) the correct value is returned string(12) "password2019" using the new OpenSSL function.

When we now store the exact same password with the new OpenSSL function, we are receiving a wrong value string(16) "password2019"

Since decryption of old passwords is working, we assume there is a glitch in the encrypt_openssl_password function. Any ideas?

travisbotello
  • 135
  • 1
  • 11
  • Have you introduced some multibyte char set in there somehow – RiggsFolly Dec 12 '19 at 18:00
  • The decrypted string gets 4 `04` bytes added to the decryption if that throws any light on the subject – RiggsFolly Dec 12 '19 at 18:10
  • 2
    Why aren't you using PHP's built-in password handling? Passwords should never ever, not even once, be decryptable. Nope. Nada. Zilch. ***NEVER*** – Jay Blanchard Dec 12 '19 at 18:19
  • 3
    Please use ***PHP's [built-in functions](http://jayblanchard.net/proper_password_hashing_with_PHP.html)*** to handle password security. If you're using a PHP version less than 5.5 you can use the `password_hash()` [compatibility pack](https://github.com/ircmaxell/password_compat). ***It is not necessary to [escape passwords](http://stackoverflow.com/q/36628418/1011527)*** or use any other cleansing mechanism on them before hashing. Doing so *changes* the password and causes unnecessary additional coding. – Jay Blanchard Dec 12 '19 at 18:22
  • If I knew that the website I was visiting could decrypt my password I would quit using them @RiggsFolly, no matter how important that site was to me. – Jay Blanchard Dec 12 '19 at 18:23
  • 1
    ^^^ Actually that **is the most important point so far**. ^^^ Well that and your previous now amended comment :) – RiggsFolly Dec 12 '19 at 18:24
  • If you need to migrate an old set of passwords it is relatively easy to develop a migration plan which you can either automate or you can have users create new passwords which are hashed. – Jay Blanchard Dec 12 '19 at 18:29
  • @JayBlanchard because this is a server monitoring application and those passwords need to be decrypted to authenticate with apache in case this particular website is using apache auth. – travisbotello Dec 13 '19 at 08:56

0 Answers0