- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
基本事实:
$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
有没有人对这个确切的问题有任何经验?有建设性的回答会有奖励!
最新
上面是一个 Blowfish 哈希示例,我试图从一个数组中重建它,它是通过 SHA512 HMACed 接收的,对称 Blowfish 加密 (CBC),url 安全 Base64 编码,urlencoded,查询字符串(呸!)。
下面是查询字符串的字符串(将上面的河豚哈希切碎)在加密、签名和 base64 编码之后,但在进行 urlencoded 之前的样子。每个字符串的长度为 128 个字符(每个字符串会随着您执行的操作越多而变得越长)。
上面是从查询字符串派生的 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.php
和 decrypt.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/
你好,我正在尝试在 opensuse 中创建一个 Shell 脚本来创建 MySqlUsers,但是当我尝试运行它时,我得到了这个错误: Warning: Could not start progra
我阅读了有关此错误的所有信息,但未能找到任何解决方案。 我有一个看起来像这样的简单页面: $xmlfile = "/var/www/marees.xml"; //Fichier dans lequel
运行 Websphere App 服务器 V8.5 Liberty Profile。我找不到任何可以解决这些警告的帮助。我在 eclipse 。 ************** He
我尝试在 GC AppEngine 上部署应用程序。部署过程中没有错误,但应用程序无法运行(仅显示加载页面)。日志中唯一一个奇怪的原始 OpenBLAS WARNING - could not det
我刚开始学习 RestKit。我正在尝试使用它来使用 Foursquare api 获取附近的 field 。但每次我尝试“objectLoader:(RKObjectLoader *)objectL
我对 Vuejs 比较陌生,每次按键时都会收到以下警告: [Vue warn]: $attrs is readonly. found in ---> at src\component
Warning: simplexml_load_file() [function.simplexml-load-file]: I/O warning : failed to load external
我在尝试修改某些表时不断收到此错误。这是我的代码: /** = 1){ //$this->mysqli->autocommit(FALSE); //insert th
当我尝试使用 PHP 的 ftp_put 函数上传文件时,早些时候出现错误: 警告:ftp_put() [function.ftp-put]:无数据连接 现在,我尝试开启被动模式: ftp_pasv(
我一直在努力让这段代码适用于现阶段的年龄。它旨在计算一个范围内的素数,我已经编写了一种方法来打印它们。不幸的是,代码将无法编译,引用警告: “警告:[未检查] 未检查调用 add(E) 作为原始类型
尝试使用带有架构组件和Kotlin的Android Studio 3 Canary 5构建示例会给出此警告。 谁能告诉我原因? 谢谢,Ove 编辑#1: 这是Dan Lew前段时间制作的样本 http
我正在编写一个 Shiny 的应用程序,它运行得非常好,突然我收到两条警告消息。我已经回到以前运行良好的副本,它们现在显示相同的错误消息,所以我真的很困惑。我的代码仍然运行并在我 Shiny 的仪表板
03-25 05:52:15.329 8029-8042/com.mgh.radio W/MediaPlayerNative: info/warning (703, 0) 03-25 05:52:15
我在构建时在我的 gradle 控制台中收到一条警告消息: 警告:[options] 引导类路径未与 -source 1.7 一起设置 1 条警告 我怎样才能解决这个问题? 任何帮助表示赞赏! 最佳答
我有下一个代码: 测试.c #include "a1.h" int main() { int a = 8; foo(a); return a; } a1.h void foo
我的程序中有一个 WORD 变量。 WORD hour; 但是当我比较它的时候 if(hour>=0 && hour=0 && hour=0 的比较,它始终适用于 hour 是 WORD 类型,它是一
安全研究人员警告称,一个最新的严重的Java错误,其本质与目前在全球范围内利用的臭名昭著的 Log4Shell 漏洞相同 。 CVE-2021-42392 尚未在国家漏洞数据库 (NVD) 中
安装SqlServer2005时“版本变更检查 (警告)"问题排查 今天同事在安装SqlServer2005时遇到“版本变更检查 (警告) ”问题导致安装失败,警告提示如下: - 版本
我的 UWP 项目中出现以下警告。我已经标记了解决方案的示例,但我更感兴趣的是为什么在同一平台上创建另一个空项目时不会出现此警告? APPX4001: Build property AppxBundl
我试图修复我的登录脚本,在我的本地主机上它可以工作,但上传到我的在线测试服务器时,注销被破坏,我得到这个错误: Warning: session_destroy() [function.session
我是一名优秀的程序员,十分优秀!