3

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

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

4

5 回答 5

1

没有可以为您提供密码块大小的 API。如果你真的需要它,你必须对 blockSize 进行硬编码(每个算法)。

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

而且,我所拥有的唯一用例mcrypt_get_block_size()mcrypt_enc_get_block_size()PKCS#7 填充,OpenSSL默认情况下已经为分组密码算法执行了该填充。因此,您可能根本不需要这个。

于 2017-02-21T13:24:19.833 回答
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;
    }
}
于 2017-05-11T18:11:34.850 回答
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));

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

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

于 2018-02-19T12:08:06.103 回答
1

可能对您有所帮助的更通用的方法涉及使用此 polyfill:mcrypt_compat。polyfill 是一个库,它实现了尚未/不再支持的功能。

第 1 步:使用 Composer 安装库

composer require phpseclib/mcrypt_compat

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

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

现在,您可以使用像mcrypt_get_block_size()这个 PHP 脚本中的函数了

于 2020-11-17T13:32:48.257 回答
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;
    }
于 2020-02-25T16:10:36.407 回答