相当于 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)。
如果我是你,我会完全改变算法。当然,这将意味着重新加密所有数据,但您最终必须这样做,现在确实是这样做的最佳时机。
我有一段旧代码是使用 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)。
如果我是你,我会完全改变算法。当然,这将意味着重新加密所有数据,但您最终必须这样做,现在确实是这样做的最佳时机。