【问题标题】:Decryption using PBEWithMD5AndTripleDES in PHP在 PHP 中使用 PBEWithMD5AndTripleDES 解密
【发布时间】:2020-12-14 20:47:45
【问题描述】:

我正在努力将 API 集成到我们的网络应用程序中。在初始请求中,API 返回使用 PBEWithMD5AndTripleDES 加密进行加密的响应,然后进行 base 64 编码。我有一个事先提供给我的加密密码。由于我缺乏经验和 PBEWithMD5AndTripleDES 文档,我正在努力解密响应。我试过使用phpseclib 没有任何运气。

这是我的 phpseclib 代码

        $res = $response->getBody()->getContents();
        $res = base64_decode($res);
        // this is provided by vendor
        $password = self::PASSWORD;
        // I tried this too.
        //$password = md5(utf8_encode($password), true);

        $tripleDes = new TripleDES(TripleDES::MODE_CBC);
        $tripleDes->setKey($password);
        $ddd = $tripleDes->decrypt($res);

        // this is returning false
        var_dump($ddd); die();

您能否提供一些关于如何在 PHP 中使用 PBEWithMD5AndTripleDES 的示例,或者指出一些方向或文档。

【问题讨论】:

  • 如果没有关于加密部分的更多信息,我们将很难为您提供帮助。您命名为“PBEWithMD5AndTripleDES”,但在我看来,这是密钥派生的算法。所以我们需要知道使用的是哪种加密算法和模式。提供样本数据集(明文、密钥、iv?、salt?、结果)也是完美的。
  • 请注意,“PBEWithMD5AndTripleDES”是一个不好使用的算法。
  • 在此处查看 phpseclib 3.0 如何使用 pbeWithMD5AndDES-CBC 做到这一点:github.com/phpseclib/phpseclib/blob/… pbeWithMD5AndTripleDES-CBC 不在我所知道的任何 IETF RFC 中。 pbeWithMD5AndDES-CBC 定义在tools.ietf.org/html/rfc2898#appendix-A.3

标签: php encryption phpseclib tripledes


【解决方案1】:

PBEWithMD5AndTripleDES 使用基于 MD5 的密钥/IV 推导算法,该算法需要密码、盐和迭代计数作为参数。在 CBC 模式 (des-ede3-cbc) 中使用 24 字节密钥加密 TripleDES。

PBEWithMD5AndTripleDESPKCS#5 (RFC 8018) 中定义的基于密码的加密的 Oracle 专有扩展,以支持更长的密钥 here。因为它是专有的,并且由于 MD5 等过时的算法以及与 AES 相比相对较慢的 TripleDES,它不应该用于新的实现,而只能用于与旧代码的兼容性。

我没有在网络上找到任何支持 PBEWithMD5AndTripleDES 开箱即用的 PHP 库(仅适用于不同的 PBEWithMD5AndDES,例如 here)。对于自定义实现,您实际上只需要派生密钥 / IV。因此,如果您也没有找到实现,但您有令人信服的理由使用此算法:Here 是实现派生的 Java 代码。到 PHP 的端口可能是:

function deriveKeyIV($key, $salt, $count){
    
    $result = "";
    for ($var = 0; $var < 4; $var++){
        if($salt[$var] != $salt[$var + 4])
        break;
    }
    if ($var == 4){
        for ($var = 0; $var < 2; $var++){
            $tmp = $salt[$var];
            $salt[$var] = $salt[3 - $var];
            $salt[3 - 1] = $tmp;
        }
    }
    for ($var = 0; $var < 2; $var++){
    
        $toBeHashed = substr($salt, $var * (strlen($salt) / 2), strlen($salt) / 2);
        for ($var2 = 0; $var2 < $count; $var2++){
            $toBeHashed = hash ("MD5", $toBeHashed . $key, TRUE);
        }
        $result = $result . $toBeHashed;
    }
    
    return $result;
}

函数返回32个字节,其中前24个字节是key,后8个字节是IV。有了这个密钥和 IV,就可以在 CBC 模式下使用 TripleDES 进行加密。

例子:

$keyIv = deriveKeyIV(hex2bin("01026161afaf0102fce2"), hex2bin("0788fe53cc663f55"), 65536);
$key = substr($keyIv, 0, 24);
$iv = substr($keyIv, 24, 8);

print(bin2hex($key) . "\n");
print(bin2hex($iv) . "\n");
print(openssl_encrypt("The quick brown fox jumps over the lazy dog", "des-ede3-cbc", $key, 0, $iv));

输出:

543650085edbbd6c26149c53a57cdd85871fd91c0f6d0be4
d7ffaa69502309ab
m4pye0texirKz1OeKqyKRJ5fSgWcpIPEhSok1SBDzgPthsw9XUuoiqXQBPdsVdUr

作为参考,我使用了 Java 实现,更准确地说是SunJCE 提供程序的 PBEWithMD5AndTripleDES 的实现,它给出了相同的结果。

请注意,PBEWithMD5AndTripleDES 的原始实现只允许 恰好 8 字节大小的盐(尽管派生函数可以处理更大的盐),否则例外是抛出(salt 必须为 8 个字节长)。要添加这个约束,可以在deriveKeyIV开头添加以下内容:

if (strlen($salt) != 8) {
    throw new Exception('Salt must be 8 bytes long');
}

【讨论】:

    猜你喜欢
    • 2021-03-26
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    相关资源
    最近更新 更多