mcrypt_decrypt() 错误更改密钥大小
Posted
技术标签:
【中文标题】mcrypt_decrypt() 错误更改密钥大小【英文标题】:mcrypt_decrypt() error change key size 【发布时间】:2015-01-30 23:53:31 【问题描述】:mcrypt_decrypt():此算法不支持大小为 15 的密钥。仅支持大小为 16、24 或 32 的键
我该如何解决这个问题?我的密钥已设置 - 无法更改。 它必须是本地更改,我认为我本地的 php 版本对于我加载的项目来说太高级了。 我该如何解决这个问题?
【问题讨论】:
您没有给我们足够的信息。您是否使用正确的密码来解密字符串(加密时使用的密码)?不同的密码支持不同的密钥大小。 php.net/manual/en/function.mcrypt-decrypt.php 项目文件可以在其他机器上运行,所以密码很好——更进一步——在重新安装我的 xampp 之前一切正常 请注意:如果您通过$key = 0x12345679ABCDEF
创建足够的 int,则传入的值是作为字符数组 -1234567
的 12-19 位(十进制)字符串,而不是32 位二进制值。 (它通过标准方法将 int 转换为字符串)。密钥必须通过“\xab\xcd\xef\x01\x02”定义为字符串(又名:数组/缓冲区)。但是在更新到 5.6 版之前,您不会意识到这已被破坏。您实际上一直在传递一个短数字字符串,该字符串填充为空
最好不要使用 PHP mcrypt,它是废弃软件,多年未更新,不支持标准 PKCS#7(née PKCS#5)填充,仅支持非标准空填充甚至不能用于二进制数据。 mcrypt 有许多出色的 bugs 可以追溯到 2003 年。mcrypt-extension is deprecated 在 PHP 7.2 中被删除。而是考虑使用defuse 或RNCryptor,它们提供了一个完整的解决方案并且正在维护并且是正确的。
【参考方案1】:
你更新到 5.6 了吗?它说
不再接受无效的密钥和 iv 大小。如果输入无效,mcrypt_decrypt() 现在将抛出警告并返回 FALSE。以前键和 IV 用 '\0' 字节填充到下一个有效大小。
Reference
阅读该引文的最后一行,您将在那里找到您的解决方案:)
mcrypt_decrypt():此算法不支持大小为 15 的密钥。仅支持大小为 16、24 或 32 的键
这意味着您需要用\0
填充您的密钥(这是以前的版本为您做的)
$key=$key."\0";
【讨论】:
那么我该如何解决这个问题?Previously keys and IVs were padded with '\0' bytes to the next valid size.
你也这样做:)
请注意,进行此更改是因为密钥应该由n / 8
字节组成,与随机无法区分,其中n
是密钥大小(以位为单位) .如果您的密钥较小,则很可能您正在为密钥使用密码。您不应该这样做,而是使用 password_hash
从密码创建密钥(如果密钥太大,可能使用最左边的字节)。
Hanky웃Panky,这是一个不向后兼容的 API 更改。
正是我需要的。谢谢【参考方案2】:
我继续创建了一个基于Hanky 웃 Panky's answer 的函数。
这可以与任何密钥长度一起使用,以确保其大小正确。
function pad_key($key)
// key is too large
if(strlen($key) > 32) return false;
// set sizes
$sizes = array(16,24,32);
// loop through sizes and pad key
foreach($sizes as $s)
while(strlen($key) < $s) $key = $key."\0";
if(strlen($key) == $s) break; // finish if the key matches a size
// return
return $key;
【讨论】:
这对我很有用。我有一个网站在旧版本的 php 上运行,我必须转移到我们的新服务器上。这让它再次工作。 循环中的循环效率低下。只需使用str_pad()
而不是while
并将<
更改为<=
并返回密钥【参考方案3】:
对于 Laravel 5
只需运行php artisan key:generate
:
Application key [EaaJgaD0uFDEg7tpvMOqKfAQ46Bqi8Va] set successfully.
如果您的密钥未更新,只需将其粘贴到您的 .env
文件中即可。
APP_KEY=EaaJgaD0uFDEg7tpvMOqKfAQ46Bqi8Va
刷新你的页面
【讨论】:
这不会破坏所有当前的加密数据,例如密码吗?【参考方案4】:我在使用 OSTicket 1.6 ST(是的旧版本,我知道)时遇到了这个问题。托管公司刚刚使用 PHP 5.6,它破坏了 cron.php 的 Mail Fetch。我发布这个希望它可以帮助其他人更快地解决这个问题。
您必须编辑文件“include/class.misc.php”。
将@troskater 编写的答案中提供的函数“pad_key”添加到“include/class.misc.php”文件中,然后在函数“解密”更改中的第 51 行添加
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $salt,...
改为使用
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, pad_key($salt),...
【讨论】:
【参考方案5】:您可以只使用 str_pad() 来实现这一点。最简单的形式就足够了。
function padKey($key)
// Get the current key size
$keySize = strlen($key);
// Set an array containing the valid sizes
$validSizes = [16,24,32];
// Loop through sizes and return correct padded $key
foreach($validSizes as $validSize)
if ($keySize <= $validSize) return str_pad($key, $validSize, "\0");
// Throw an exception if the key is greater than the max size
throw new Exception("Key size is too large");
其他答案就可以了。我只是在这里利用内置的 PHP 函数 str_pad 而不是在循环中附加“\0”。
【讨论】:
【参考方案6】:您不需要用“\0”填充键。
我在迁移到新的 PHP 7 服务器时遇到了同样的问题,我收到了消息:
mcrypt_decrypt():此算法不支持大小为 19 的密钥。仅有的 支持大小为 16、24 或 32 的键。
我在代码中的键是一个 19 个字符的字符串,我只是将它更改为一个 32 个字符的字符串,一切都很好了。
因此,如错误消息所示,请使用有效的大小键。
【讨论】:
我的密钥已设置 - 无法更改。它必须是本地更改 对。就我而言,我可以更改密钥。 我很感激你。但有一些困惑。这是个好主意吗?如果是这样,那么 DB 的变化呢?【参考方案7】:我遇到了同样的问题,但是用这个解决了它
public function setKey($key)
$len = strlen($key);
if($len < 24 && $len != 16)
$key = str_pad($key, 24, "\0", STR_PAD_RIGHT);
elseif ($len > 24 && $len < 32)
$key = str_pad($key, 32, "\0", STR_PAD_RIGHT);
elseif ($len > 32)
$key = substr($key, 0, 32);
$this->key = $key;
【讨论】:
【参考方案8】:如果您的加密代码如下所示:
<?php
function encryptCookie($value)
if(!$value)return false;
$key = 'aNdRgUkXp2s5v8y/B?E(H+MbQeShVmYq';
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
return trim(base64_encode($crypttext)); //encode for cookie
function decryptCookie($value)
if(!$value)return false;
$key = 'aNdRgUkXp2s5v8y/B?E(H+MbQeShVmYq';
$crypttext = base64_decode($value); //decode cookie
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);
return trim($decrypttext);
?>
您需要将 $key 更改为 128 或 256 位加密代码。我只是复制了从这里生成的代码:Generate Code
我为我创建了一个由 32 个字符组成的 256 位代码,从而解决了无效密钥大小为 15 或任何导致错误的数字的问题。因此,无论为 $key 设置什么,您都需要将其更改为有效代码,然后它应该可以正常工作。
【讨论】:
以上是关于mcrypt_decrypt() 错误更改密钥大小的主要内容,如果未能解决你的问题,请参考以下文章
更新到 php 5.6.2 时的 mcrypt 警告;不支持大小为 x 的密钥
php使用内置的mcrypt_encrypt和mcrypt_decrypt进行字符串加密解密
有啥方法可以创建密钥大小为 512 的 JWT 令牌?并更改 AsymmetricSignatureProvider 的默认最小尺寸要求