【发布时间】:2016-10-15 23:13:59
【问题描述】:
基本事实:
$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 和基本密文(这是课程的标准)。
问题
PHP: Warning mcrypt_generic_init(): Iv size is incorrect; supplied length: 12, needed: 8
假设我已经梳理了 PHP 手册和 Stackoverflow。假设我看过其他类似的问题,但不完全像这个。假设我搜索了互联网无济于事。假设我有足够的经验来正确设置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 散列那样。
【问题讨论】:
-
在我使用 ryndael 128 时遇到了类似的问题。花了几个小时寻找原因,但发现 mcrypt 没有得到积极维护,并切换到 openssl 加密,到目前为止运行良好。这是一个猜测,但我认为问题在于密钥的派生/重新创建方式。
-
@Nitin 我尝试确保用于密钥的字符串长度至少为 56 个字符。此外,我还集成了 base64_encode 的 url 安全版本。我能想到的唯一另一件事是将密钥作为二进制数据返回并以这种方式使用。
-
@Nitin 显然,返回的 IV 是 ISO-8859-1。当我将它转换为 UTF-8 时,IV 总是报告它是 8 个字节。我可能已经解决了这个问题。
-
@Nitin 也许我应该在加密期间强制使用 ISO-8859-1 IV 并将传入的 IV (mb, UTF8,) 转换为 ISO-8859-1 IV。那可能是票。
-
这 12 个 字节 可能是因为您使用了 mb_substr(),它接受字符,而不是字节。使用 substr(),8 将占用 8 个字节。编码永远不会成为问题,因为输出要么是二进制的(使用 base64),要么是 ascii 安全的(mb 与否都不会产生影响)。
标签: php encryption utf-8 mcrypt