-3

The mcrypt module is deprecated in PHP 7.1, so I have to refactor my old encrypt / decrypt functions with the openssl functions. Actually I found no way doing this.

My major problem is: The script still must be able to decrypt existing crypted data. I have no chance to decrypt with my function und re-crypt the data with a new function again!

Here's my existing code:

function _encrypt($cleartext, $key = "th1s1sav3rys3cr3tk3y") {
  if ($cleartext) {
    $td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $encrypted_data_raw = mcrypt_generic($td, $cleartext);
    $encrypted_data = bin2hex($encrypted_data_raw);        
    mcrypt_generic_deinit($td);
    return $encrypted_data;
  } else {
    return false;
  }
}

function _decrypt($crypttext, $key = "th1s1sav3rys3cr3tk3y") {
  if ($crypttext) {
    $td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $decrypted_data = trim(mcrypt_decrypt(MCRYPT_TripleDES, $key, hex2bin($crypttext), MCRYPT_MODE_ECB, $iv));
    mcrypt_generic_deinit($td);
    return $decrypted_data;
  } else {
    return false;
  }
}

UPDATE: This is the way I tried so solve it - to get the same $iv i took simply the same code as in the old function and try to implement it in the way described here: php: mcrypt_encrypt to openssl_encrypt, and OPENSSL_ZERO_PADDING problems

function _encrypt2($cleartext, $key = "th1s1sav3rys3cr3tk3y") {
    $td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);        
    $message_padded = $cleartext;
    if (strlen($message_padded) % 8) {
        $message_padded = str_pad($message_padded,
        strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
    }
    $encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
    return bin2hex($encrypted_openssl);
}

I hope you can give me good hints.

Marco
  • 2,409
  • 4
  • 16
  • 23
  • What kind of data are you actually trying to encrypt? Passwords, personal user data? – GrumpyCrouton Jan 08 '18 at 18:32
  • 1
    did you not Google that? there are alternatives and you'll also find a few here on Stack. The manual also states it *Alternatives to this function include: [random_bytes()](https://php.net/manual/en/function.random-bytes.php)* – Funk Forty Niner Jan 08 '18 at 18:34
  • @GrumpyCrouton: The data are text snippets. – Marco Jan 08 '18 at 18:40
  • @Funk Forty Niner: I googled a lot about this, but I didn't find the right way to solve this problem. – Marco Jan 08 '18 at 18:41
  • @LawrenceCherone: I tried with openssl_encrypt and took aes-256-cbc as MCRYPT_TripleDES replacement, but the I was not able to produce the same text. – Marco Jan 08 '18 at 18:43
  • 1
    uhhh, maybe you should not use an *entirely different algorithm* if you're looking to replicate 3DES. Tip: Look in the comments of [`openssl_encrypt()`](http://php.net/manual/en/function.openssl-encrypt.php) because they answer this exact question. – Sammitch Jan 08 '18 at 18:46
  • @LawrenceCherone: Yes... "DES-EDE3-CBC" should work... but didn't ... – Marco Jan 08 '18 at 18:49
  • Try https://stackoverflow.com/questions/41740600/php7-1-mcrypt-alternative --- https://stackoverflow.com/questions/41272257/mcrypt-is-deprecated-what-is-the-alternative --- https://stackoverflow.com/questions/44427815/alternative-to-mcrypt-encrypt --- if you haven't already seen/tried those. – Funk Forty Niner Jan 08 '18 at 19:13
  • @FunkFortyNiner: I've seen/read these threads already, but there was no solution for me. – Marco Jan 08 '18 at 19:43
  • alrighty then. Well, there isn't much else I can do here, sorry. – Funk Forty Niner Jan 08 '18 at 19:44
  • 1
    See [Use openssl_encrypt to replace Mcrypt for 3DES-ECB encryption](http://stackoverflow.com/q/39467008/608639), [Can't decrypt using pgcrypto from AES-256-CBC but AES-128-CBC is OK](http://stackoverflow.com/q/43550818/608639), [MCrypt rijndael-128 to OpenSSL aes-128-ecb conversion](http://stackoverflow.com/q/45218465/608639), etc. Also see [Upgrading my encryption library from Mcrypt to OpenSSL](http://stackoverflow.com/q/43329513), [Replace Mcrypt with OpenSSL](http://stackoverflow.com/q/9993909/608639) and [Preparing for removal of Mcrypt in PHP 7.2](http://stackoverflow.com/q/42696657) – jww Jan 09 '18 at 00:09

1 Answers1

2

Finally I got the solution - thank you all for your help and support by pushing me into the right direction and asking the right questions. The main thing I missed was ECB-Mode (I took CBC...). So all the stuff with the $iv wasn't really needed.

To complete the answer here my new functions:

function _encrypt_openssl($cleartext, $key = "th1s1sav3rys3cr3tk3y") {
   if ($m = strlen($cleartext) %8) {
      $cleartext .= str_repeat("\0", 8-$m);
   } 
   $encrypted_openssl = openssl_encrypt($cleartext , "DES-EDE3-ECB", $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, null);
   return bin2hex($encrypted_openssl);
}

function _decrypt_openssl($crypttext, $key = "th1s1sav3rys3cr3tk3y") {
   return openssl_decrypt(hex2bin($crypttext), 'DES-EDE3-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, null);
}
Marco
  • 2,409
  • 4
  • 16
  • 23
  • For symmetric encryption, the `OPENSSL_ZERO_PADDING` flag should be used instead of `OPENSSL_NO_PADDING` (contrary to expectation, `OPENSSL_ZERO_PADDING` does not enable Zero padding, but _disables_ padding). `OPENSSL_NO_PADDING` is defined for asymmetric encryption, has a value of 3, and would therefore _unintentionally_ set `OPENSSL_RAW_DATA` (with a value of 1) in addition to `OPENSSL_ZERO_PADDING` (with a value of 2) in the context of symmetric encryption. Generally this would lead to an _unexpected_ result (here it is unproblematic, because `OPENSSL_RAW_DATA` is set anyway). – Topaco Feb 01 '21 at 08:27