Openssl 相当于 mcrypt_get_block_size

Openssl equivalent to mcrypt_get_block_size

我目前正在用 OpenSSL 替换 Mcrypt,因为 Mcrypt 将在 PHP 7.1 中被弃用。我需要一种方法来获取每个算法的块大小,例如 mcrypt_get_block_size().

我想知道是否有与 mcrypt_get_block_size() 等效的功能,但它的文档非常糟糕,似乎找不到它。

不幸的是,

没有 API 可以为您提供密码块大小。如果你真的需要它,你必须hard-code blockSize(根据算法)。

但是,典型的应用程序只需要支持一种加密算法,在这种情况下,您应该已经知道适合您的情况的块大小。

而且,我对 mcrypt_get_block_size()mcrypt_enc_get_block_size() 的唯一用例是 PKCS#7 填充,OpenSSL 默认情况下已经这样做了用于分组密码算法。所以可能你根本不需要这个。

以下函数可以用来替代PHP >= 5.4.0。 它只是暴力破解 openssl_encrypt().

中的块长度
if (!function_exists('openssl_cipher_block_length')) {
    /**
     * Returns the block length for a given cipher.
     *
     * @param string $cipher
     *      A cipher method (see openssl_get_cipher_methods()).
     *
     * @retval int
     *      The cipher's block length.
     *      Returns false if the actual length cannot be determined.
     *      Returns 0 for some cipher modes that do not use blocks
     *      to encrypt data.
     *
     * @note
     *      PHP >= 5.4.0 is required for this function to work.
     */
    function openssl_cipher_block_length($cipher)
    {
        $ivSize = @openssl_cipher_iv_length($cipher);

        // Invalid or unsupported cipher.
        if (false === $ivSize) {
            return false;
        }

        $iv = str_repeat("a", $ivSize);

        // Loop over possible block sizes, from 1 upto 1024 bytes.
        // The upper limit is arbitrary but high enough that is
        // sufficient for any current & foreseeable cipher.
        for ($size = 1; $size < 1024; $size++) {
            $output = openssl_encrypt(
                // Try varying the length of the raw data
                str_repeat("a", $size),

                // Cipher to use
                $cipher,

                // OpenSSL expands the key as necessary,
                // so this value is actually not relevant.
                "a",

                // Disable data padding: php_openssl will return false
                // if the input data's length is not a multiple
                // of the block size.
                //
                // We also pass OPENSSL_RAW_DATA so that PHP does not
                // base64-encode the data (since we just throw it away
                // afterwards anyway)
                OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,

                // Feed it with an IV to avoid nasty warnings.
                // The actual value is not relevant as long as
                // it has the proper length.
                $iv
            );

            if (false !== $output) {
                return $size;
            }
        }

        // Could not determine the cipher's block length.
        return false;
    }
}

我认为你可以这样做:

$method = 'AES-256-CBC';
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));
$block_size = strlen(openssl_encrypt('', $method, '', OPENSSL_RAW_DATA, $iv));

它基本上是加密一个空字符串,由于数据将被填充到块大小,检查结果长度。

我用一些不同的方法测试了它,它似乎工作正常。

txigreman 这个解决方案对我有用,我设法更改了 MCRYPT 代码以使用 OPENSSL 这是我的加密功能,它取代了 MCRYPT 我混合了一些来自 MCRYPT 的代码和来自 openssl 的新代码,虽然解密不起作用但我可以打开提供商的支付页面并完成支付 - 这就是我需要的,然后将我重定向到成功页面, NeO.network.ae 支付网关

public $method = 'aes-256-cbc';

$this->EncryptedString                      = $this->encryptData($this->beforeEncryptionString, $this->merchantKey, $this->method);

    public function encryptData(string $data, string $key, string $method): string
    {
        $ivSize = openssl_cipher_iv_length($method);
        $iv = 'YOUR_IV';
        $size               = strlen(openssl_encrypt('', $method, '', OPENSSL_RAW_DATA, $iv));
        $pad                = $size - ( strlen( $data ) % $size );
        $padtext            = $data . str_repeat( chr( $pad ), $pad );
        $encrypted = openssl_encrypt($padtext, $method, base64_decode( $key ), OPENSSL_RAW_DATA, $iv);

        $encrypted = base64_encode($encrypted);

        return $encrypted;
    }

一种可能对您有所帮助的更通用的方法涉及使用此 polyfill:mcrypt_compat。 polyfill 是一个实现不受支持的功能的库 yet/anymore。

第 1 步:使用 Composer 安装库

composer require phpseclib/mcrypt_compat

第 2 步: 在使用 mcrypt 函数的 PHP 脚本顶部需要 Composer 的自动加载器(确保相对路径正确)

require_once('../vendor/autoload.php');

现在,您可以在此 PHP 脚本中使用 mcrypt_get_block_size() 等函数