gpt4 book ai didi

PHP: 警告 mcrypt_generic_init(): Iv 大小不正确;供应长度:12,需要:8

转载 作者:可可西里 更新时间:2023-11-01 12:59:46 25 4
gpt4 key购买 nike

基本事实:

$algorithm  = MCRYPT_BLOWFISH;
$mode = MCRYPT_MODE_CBC;
$randSource = MCRYPT_DEV_URANDOM;

注意这不是一个严格的编码问题。

上下文:

CentOS 7、Apache 2.4.12 和 PHP 5.6.20。

我正在制作一封带有“验证您的电子邮件地址”链接的 HTML 电子邮件,该链接允许完成注册过程。我的虚拟专用服务器上的所有内容都是 UTF-8,所有表单和查询字符串输入都使用多字节 (mb) 函数进行处理。

背景

作为实验(我知道 mcrypt 库的年龄和状态),我正在尝试解密 Blowfish 加密的查询字符串参数。假设在上升过程中,加密序列运行良好,我正在收到带有链接的电子邮件。

在下降的过程中,hmac_hash() 签名(SHA-512,仅用于此实验)正在运行,我能够将每个独立的消息(32 个字符)与其哈希校验和分开( 128 个字符)。分离消息部分的 Base64 解码正在运行。对于每个参数,我都留下了复合密文,其中复合密文等于IV + 基本密文。假设我使用substr()一个版本 来独立获取 IV 和基本密文(这对类(class)来说是标准的)。

问题

PHP: Warning  mcrypt_generic_init(): Iv size is incorrect; supplied length: 12, needed: 8

假设我已经梳理了 PHP 手册和 Stackoverflow。假设我看过其他类似的问题,但不完全像这个问题。假设我在 Internet 上搜索无果。假设我有足够的经验来正确设置 mb_string。假设当我解决当前这个问题时,我会处理 mcrypt 填充。

多字节问题会干扰解密吗?

base64 编码 IV + base cipher text 会破坏 IV 吗?

base64 填充会是个问题吗?

我应该指定一个更具体的 MCRYPT_BLOWFISH_* 吗?

为什么河豚 IV 大小报告 8 字节,但很少产生 8 字节 IV?

我应该使用哪个 substr(),substr()mb_substr(),用于倾向于将所有内容都设为 UTF-8 并将所有其他输入处理为多字节 UTF-8。我知道这是一个奇怪的问题,但是所有 PHP 手册 mycrypt 解密序列示例都使用 substr(),而没有一个使用 mb_substr()。我网站上的所有内容都尽可能使用 mb_functions,如果 substr() 解决了我的问题,我不介意使用它,但它并没有解决问题。当我使用 mb_substr() 时,我收到以下警告。

PHP: Warning  mcrypt_generic_init(): Iv size is incorrect; supplied length: 11, needed: 8

有没有人对这个确切的问题有任何经验?有建设性的回答会有奖励!

最新

Goal: To recreate a hash, like this, from a Blowfish encrypted query string.

上面是一个 Blowfish 哈希示例,我试图从一个数组中重建它,它是通过 SHA512 HMACed 接收的,对称 Blowfish 加密 (CBC),url 安全 Base64 编码,urlencoded,查询字符串(呸!)。

下面是查询字符串的字符串(将上面的河豚哈希切碎)在加密、签名和 base64 编码之后,但在进行 urlencoded 之前的样子。每个字符串的长度为 128 个字符(每个字符串会随着您执行的操作越多而变得越长)。

enter image description here

Decrypted Array

上面是从查询字符串派生的 Base64 解码和 Blowfish 解密数组(显然,在这个结果之间有安全步骤,但我只是想展示事物的最新状态。)有些地方不对。加密似乎没有任何错误。解密也不会产生任何错误。纯文本是错误的。如果我加入/分解这些元素,它们将不会像上面的 Blowfish 哈希那样。

最佳答案

我猜想这个问题会隐藏在 UTF-8 编码的某个地方,因为您在不正确的上下文中使用它。也可能是您的框架对所有用例都有一些魔力。这可能太多了,通常会导致安全漏洞或类似的错误,因为您没有在真正需要做的时候做真正需要做的事情。

PHP 中的字符串只是字节的集合。你可以在那里存储文本,在你选择的编码中,或者你可以在那里存储二进制数据,比如图像。 PHP 既不知道什么字符串中有什么数据,也不知道那里使用什么编码。这取决于开发人员跟踪此信息。

使用加密时,您会在生成随机字符串或加密某些有效负载时获得二进制数据。它保存在字符串中,但它没有 UTF-8 编码,因为它只是字节。我什至不会说它的编码是 ISO-8859-1,因为这意味着字节 77 (0x4D) 代表字母“M”。但实际上,它只是数字 - 77 根本不代表任何字母。

还有一点要补充——对于 ASCII 符号(拉丁字母、数字等——0-127 字节值),它需要一个字节来表示 UTF-8 编码中的符号(与 ISO-8859 相同)。因此,就您传递的 base64_encode 数据而言,您不必太担心。 mb_substr 也将以与 substr 相同的方式工作。 但是! 对于二进制数据,您不能使用 mb_* 函数,因为它适用于字符。例如,如果加密数据是两个字节0xC5 0xA1,它只是UTF-8 中的单个符号。加密适用于字节(直到最终结果,它可以是任何东西 - 甚至是二进制文件),而不是字符。

由于您没有提供任何代码,我已经为您提供了一些 - 我希望它能帮助您解决问题(如果它仍然相关的话)。

为了显示 URL 中传递的参数,有两个文件:encrypt.phpdecrypt.php。保存到一个目录,在其中运行 php -S localhost:8000 并转到 http://localhost:8000/encrypt.php

encrypt.php:

<?php
// mcrypt_enc_get_key_size($td) gives 56, so it's longest that this key can be
$key = 'LedsoilgarvEwAbDavVenpirabUfjaiktavKekjeajUmshamEsyenvoa';
$data = 'This is very important data, with some š UTF-8 ĘĖ symbols';

$td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');

// create random IV - it's just random 8 bytes. You should use random_bytes() instead if available
$ivSize = mcrypt_enc_get_iv_size($td);
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);

mcrypt_generic_init($td, $key, $iv);

$encrypted = mcrypt_generic($td, $data);

mcrypt_generic_deinit($td);
mcrypt_module_close($td);

// payload that you want to send - binary. It's neither UTF-8 nor ISO-8859-1 - it's just bytes
$payload = $iv . $encrypted;

// base64 to pass safely
$base64EncodedPayload = base64_encode($payload);
// URL encode for URL. No need to do both URL-safe base64 *and* base64 + urlencode
$link = 'http://localhost:8000/decrypt.php?encryptedBase64=' . urlencode($base64EncodedPayload);

// in fact, just for the reference, you don't even need base64_encode - urlencode also works at byte level
// base64_encode takes about 1.33 more space, but urlencode takes 3 times more than original for non-safe symbols, so base_64 will probably be shorter
$link2 = 'http://localhost:8000/decrypt.php?encrypted=' . urlencode($payload);

?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<pre><?php
var_dump('Data:', $data);
var_dump('Data size in bytes:', strlen($data));
var_dump('Data size in characters - smaller, as 3 of the characters take 2 bytes:', mb_strlen($data, 'UTF-8'));
var_dump('Encrypted data size in bytes - same as original:', strlen($encrypted));
var_dump('Encrypted data size in characters - will be pseudo-random each time:', mb_strlen($encrypted, 'UTF-8'));

var_dump('IV base64 encoded:', base64_encode($iv));
var_dump('Encrypted string base64 encoded:', base64_encode($encrypted));
?></pre>
<!-- Link will not contain any special characters, so htmlentities should not make any difference -->
<!-- In any case, I would still recommend to use right encoding at the right context to avoid any issues if something changes -->
<a href="<?php echo htmlentities($link, ENT_QUOTES, 'UTF-8');?>">Link to decrypt</a><br/>
<a href="<?php echo htmlentities($link2, ENT_QUOTES, 'UTF-8');?>">Link to decrypt2</a>
</body>
</html>

解密.php:

<?php
$key = 'LedsoilgarvEwAbDavVenpirabUfjaiktavKekjeajUmshamEsyenvoa';

if (isset($_GET['encryptedBase64'])) {
// just get base64_encoded symbols (will be ASCII - same in UTF-8 or other encodings)
$base64EncodedPayload = $_GET['encryptedBase64'];
$payload = base64_decode($base64EncodedPayload);
} else {
// just get binary string from URL
$payload = $_GET['encrypted'];
}

$td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');

$ivSize = mcrypt_enc_get_iv_size($td);

$iv = substr($payload, 0, $ivSize);
$encrypted = substr($payload, $ivSize);

mcrypt_generic_init($td, $key, $iv);

/* Decrypt encrypted string */
$decrypted = mdecrypt_generic($td, $encrypted);

/* Terminate decryption handle and close module */
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<pre><?php
var_dump('IV base64 encoded:', base64_encode($iv));
var_dump('Encrypted string base64 encoded:', base64_encode($encrypted));
var_dump('Result:', $decrypted);
?></pre>
</body>
</html>

关于PHP: 警告 mcrypt_generic_init(): Iv 大小不正确;供应长度:12,需要:8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37825261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com