【问题标题】:Equivalent Encryption for MCRYPT - To preserve client side codeMCRYPT 的等效加密 - 保留客户端代码
【发布时间】:2019-08-17 14:58:01
【问题描述】:

我正在使用以下代码使用 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);
    ?>

较新版本的 php 贬低了 mcrypt,我正在寻找一个替代品,它可以使用相同的密钥并产生相同的结果,这样我就不需要更改客户端代码。

【问题讨论】:

  • 我建议您更改它。 MCRYPT_RIJNDAEL_256 不是 AES 是非常古老且非标准的。我建议您使用经过身份验证的加密模式,如 AES-GCM 或 ChaCha20Poly1305。
  • 不推荐使用 mcrypt 的一个重要原因是它提倡不安全的加密方法。如果我查看您的代码,我们有一个实际上是(短)密码的密钥、ECB 模式加密(实际上不使用 IV)和可以去除尾随零字节的零填充(尽管 trim 函数会否则这样做)。正如 kelalaka 已经指出的那样,这是您没有使用 AES 的基础。您需要建立一个安全协议并转换为该协议。
  • @kelalaka 好吧.. 会的。
  • @MaartenBodewes 好吧.. 会的。

标签: php encryption mcrypt


【解决方案1】:

我是 RFC to deprecate then remove mcrypt from PHP 的作者。

您绝对应该做的是迁移您的数据以改用新的 Sodium 扩展。 Learn how to get started with libsodium in PHP。代码示例可以安全使用。

<?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);
}

如果您需要在 PHP 7.1 和更早版本以及 PHP 7.2 和更新版本之间进行“过渡”步骤,mcrypt_compat 是一个由 phpseclib 开发人员创建的 polyfill 库,用于促进 mcrypt 和非废弃软件库(OpenSSL、Sodium)之间的迁移.

仅用于迁移。不要依赖它来“正常工作”并确保安全。

【讨论】:

  • 感谢您的回答。我升级了PHP版本并使用了AES加密方案。
猜你喜欢
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 2011-08-19
  • 2017-10-18
  • 1970-01-01
相关资源
最近更新 更多