Openssl等同于mcrypt_get_block_size

时间:2017-02-20 16:53:52

标签: php encryption mcrypt php-openssl php-7.1

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

我想知道是否有一个与mcrypt_get_block_size()相同的功能,但它的记录非常糟糕似乎无法找到它。

5 个答案:

答案 0 :(得分:1)

以下函数可用作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;
    }
}

答案 1 :(得分:1)

我认为你可以这样做:

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

它基本上加密了一个空字符串,并且,当数据填充到块大小时,检查结果长度。

我已经用一些不同的方法对它进行了测试,它似乎运行正常。

答案 2 :(得分:1)

更通用的方法可能会帮助您涉及使用此polyfill:mcrypt_compat。 polyfill是一个实现了尚不支持的功能的库。

步骤1 :使用Composer安装库

composer require phpseclib/mcrypt_compat

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

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

现在,您可以在此PHP脚本中使用mcrypt_get_block_size()之类的功能

答案 3 :(得分:0)

很遗憾,

没有能够为您提供密码blockSize的API。如果确实需要它,则必须对blockSize进行硬编码(每种算法)。

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

此外,我mcrypt_get_block_size()mcrypt_enc_get_block_size()的唯一用例是PKCS#7填充,OpenSSL 默认情况下已经使用进行分组密码算法。所以你可能根本就不需要这个。

答案 4 :(得分:0)

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