4

I'm using the following code to perform encryption using mcrypt

<?PHP

    define('SECURE_KEY','Somekey');

    function encrypt($value){
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $value, MCRYPT_MODE_ECB, $iv);
    }

    function decrypt($value){
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $value, MCRYPT_MODE_ECB, $iv));
    }
    $temp=encrypt("teststring");
    printf($temp);
    ?>

The newer versions of php depreciates mcrypt,im looking for a replacement for the same that works with the same key and produces the same result,so that i dont need to change client side code.

techno
  • 6,100
  • 16
  • 86
  • 192
  • 2
    I recommend you to change it. It is very old and nonstandard that is `MCRYPT_RIJNDAEL_256` is not [AES](https://www.php.net/manual/en/function.mcrypt-encrypt.php). I suggest you use authenticated encryption modes as AES-GCM or ChaCha20Poly1305. – kelalaka Mar 27 '19 at 09:36
  • 2
    One of the big reason why mcrypt is being deprecated is because it promotes insecure encryption methods. If I look at your code, we have a key that's really a (short) password, ECB mode encryption (which actually doesn't use an IV) and zero padding which could strip of trailing zero bytes (although the `trim` function would otherwise do that). That's on top of the fact that you're not using AES, as kelalaka has already indicated. You need to establish a secure protocol and convert to that. – Maarten Bodewes Mar 27 '19 at 11:53
  • @kelalaka okay.. will do. – techno Mar 27 '19 at 17:47
  • @MaartenBodewes okay.. will do. – techno Mar 27 '19 at 17:48

1 Answers1

4

I'm the author of the RFC to deprecate then remove mcrypt from PHP.

What you should absolutely do is migrate your data to use the new Sodium extension instead. Learn how to get started with libsodium in PHP. The code examples are safe to use.

<?php
/**
 * Wrap crypto_aead_*_encrypt() in a drop-dead-simple encryption interface
 *
 * @link https://paragonie.com/b/kIqqEWlp3VUOpRD7
 * @param string $message
 * @param string $key
 * @return string
 */
function simpleEncrypt($message, $key)
{
    $nonce = random_bytes(24); // NONCE = Number to be used ONCE, for each message
    $encrypted = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt(
        $message,
        $nonce,
        $nonce,
        $key
    );
    return $nonce . $encrypted;
}

/**
 * Wrap crypto_aead_*_decrypt() in a drop-dead-simple decryption interface
 *
 * @link https://paragonie.com/b/kIqqEWlp3VUOpRD7
 * @param string $message - Encrypted message
 * @param string $key     - Encryption key
 * @return string
 * @throws Exception
 */
function simpleDecrypt($message, $key)
{
    $nonce = mb_substr($message, 0, 24, '8bit');
    $ciphertext = mb_substr($message, 24, null, '8bit');
    $plaintext = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt(
        $ciphertext,
        $nonce,
        $nonce,
        $key
    );
    if (!is_string($plaintext)) {
        throw new Exception('Invalid message');
    }
    return $plaintext;
}

$secretKey = random_bytes(32);
$message = 'Test message';

/* Encrypt the message: */
$ciphertext = simpleEncrypt($message, $secretKey);

/* Decrypt the message: */
try {
    $decrypted = simpleDecrypt($ciphertext, $secretKey);
    var_dump(hash_equals($decrypted, $message));
    /* bool(true) */
} catch (Exception $ex) {
    /* Someone is up to no good */
    exit(255);
}

If you need a "transition" step between PHP 7.1 and older, and PHP 7.2 and newer, mcrypt_compat is a polyfill library created by the phpseclib developers to facilitate migrations between mcrypt and non-abandonware libraries (OpenSSL, Sodium).

Only use it for migrations. Don't rely on it to "just work" and be secure.

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206