相当于 PhpSecLib 中的 mcrypt_encrypt

equivalent of mcrypt_encrypt in PhpSecLib

我有一段旧代码是使用 mcrypt 扩展编写的,我必须将其更改为 phpseclib。但是我的代码不会生成与 mcrypt 函数相同的输出:

旧代码:

$encryptedText =mcrypt_encrypt(
        MCRYPT_RIJNDAEL_256,
        $myKey,
        $data ,
        MCRYPT_MODE_CBC,
        $myIV
    );

我的新密码:

$aes = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CBC);
$aes->setKey($myKey);
$aes->setIV($myIV);
$aes->disablePadding();
$seclib = $aes->encrypt( $data );

但是$encryptedText$seclib不一样。

您将 Rijndael 等同于 AES,这是一种常见的误解。

AES 只是它的一个子集 - Rijndael-128,AES 变体之间的区别只是密钥大小:

  • AES-128 是具有 128 位密钥的 Rijndael-128。
  • AES-256 又是 Rijndael-128,但具有 256 位密钥。

另一方面,Rijndael 变体中的后缀数字指的是密钥大小 和块大小 ,所以当然你不能通过 AES 获得 Rijndael-256,因为你需要 256 位块大小。

phpseclib 文档上有一个页面,它会在您输入基本变量(密码、模式、密钥大小、位大小)后生成示例代码。它为 Rijndael, CBC, 256, 256 输出以下内容:

<?php
include('Crypt/Rijndael.php');
include('Crypt/Random.php');

$cipher = new Crypt_Rijndael(); // could use CRYPT_RIJNDAEL_MODE_CBC
$cipher->setBlockLength(256);
// keys are null-padded to the closest valid size
// longer than the longest key and it's truncated
//$cipher->setKeyLength(256);
$cipher->setKey('abcdefghijklmnopqrstuvwxyz123456');
// the IV defaults to all-NULLs if not explicitly defined
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3));

$size = 10 * 1024;
$plaintext = str_repeat('a', $size);

echo $cipher->decrypt($cipher->encrypt($plaintext));

我不确定库是否真的支持这个没有 mcrypt 可用性的密码,但它应该。


我假设你这样做是因为 mcrypt 正在从 PHP 中删除,我强烈建议你改变你的策略。

即使上面的方法有效,当使用算法的用户空间 PHP 实现时它会很慢(在 phpseclib 文档中有说明),但更重要的是 - 你将没有其他如果这个库停止工作,不再维护等,则有替代方案。Rijndael 的非 AES 变体并不普遍,而且今天有更多现代算法可用(提示:libsodium 被添加到 PHP 7.2)。

如果我是你,我会完全改变算法。当然,这将意味着重新加密所有数据,但您最终必须这样做,现在确实是这样做的最佳时机。