在PHP中使用PBEWithMD5AndTripleDES解密

如何解决在PHP中使用PBEWithMD5AndTripleDES解密

我正在将API集成到我们的Web应用程序中。在初始请求上,API返回一个响应,该响应使用PBEWithMD5AndTripleDES加密进行加密,然后以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 使用基于MD5的算法进行密钥/ IV派生,该算法期望密码,密码和迭代计数作为参数。为了加密,使用具有24字节密钥的CBC模式(des-ede3-cbc)中的TripleDES。

PBEWithMD5AndTripleDES 是对PKCS#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个字节为键,后8个字节为IV。使用此密钥和IV,可以在CBC模式下使用TripleDES进行加密。

示例:

$keyIv = deriveKeyIV(hex2bin("01026161afaf0102fce2"),hex2bin("0788fe53cc663f55"),65536);
$key = substr($keyIv,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,$iv));

输出:

543650085edbbd6c26149c53a57cdd85871fd91c0f6d0be4
d7ffaa69502309ab
m4pye0texirKz1OeKqyKRJ5fSgWcpIPEhSok1SBDzgPthsw9XUuoiqXQBPdsVdUr

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

请注意, PBEWithMD5AndTripleDES 的原始实现只允许大小为精确 8个字节的盐(尽管派生函数可以处理较大的盐),否则将出现异常引发(盐必须为8个字节长)。要添加此约束,可以在deriveKeyIV的开头添加以下内容:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?