在 PHP 中使用 PBEWithMD5AndTripleDES 解密
Decryption using PBEWithMD5AndTripleDES in PHP
我正在努力将 API 集成到我们的网络应用程序中。在初始请求中,API returns 响应使用 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 使用基于 MD5 的算法进行密钥/IV 推导,该算法需要密码、盐和迭代计数作为参数。对于采用 24 字节密钥的 CBC 模式 (des-ede3-cbc
) 中的加密,应用了 TripleDES。
PBEWithMD5AndTripleDES 是 PKCS#5 (RFC 8018) to support longer keys, here 中定义的 password-based 加密的 Oracle 专有扩展。因为它是专有的,并且由于 MD5 等过时的算法和与 AES 相比相对较慢的 TripleDES,它不应该用于新的实现,而只是为了与旧代码兼容。
我还没有在网上找到任何支持 PBEWithMD5AndTripleDES out-of-the-box 的 PHP 库(仅针对不同的 PBEWithMD5AndDES,例如 here). For a custom implementation you actually only need the derivation of the key / IV. So if you don't find an implementation either, but you have compelling reasons to use this algorithm: 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;
}
函数returns32字节,其中前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 字节大小的盐(尽管推导函数可以处理更大的盐),否则抛出异常(盐必须是 8 字节长)。要添加此约束,可以在 deriveKeyIV
开头添加以下内容:
if (strlen($salt) != 8) {
throw new Exception('Salt must be 8 bytes long');
}
我正在努力将 API 集成到我们的网络应用程序中。在初始请求中,API returns 响应使用 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 使用基于 MD5 的算法进行密钥/IV 推导,该算法需要密码、盐和迭代计数作为参数。对于采用 24 字节密钥的 CBC 模式 (des-ede3-cbc
) 中的加密,应用了 TripleDES。
PBEWithMD5AndTripleDES 是 PKCS#5 (RFC 8018) to support longer keys, here 中定义的 password-based 加密的 Oracle 专有扩展。因为它是专有的,并且由于 MD5 等过时的算法和与 AES 相比相对较慢的 TripleDES,它不应该用于新的实现,而只是为了与旧代码兼容。
我还没有在网上找到任何支持 PBEWithMD5AndTripleDES out-of-the-box 的 PHP 库(仅针对不同的 PBEWithMD5AndDES,例如 here). For a custom implementation you actually only need the derivation of the key / IV. So if you don't find an implementation either, but you have compelling reasons to use this algorithm: 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;
}
函数returns32字节,其中前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 字节大小的盐(尽管推导函数可以处理更大的盐),否则抛出异常(盐必须是 8 字节长)。要添加此约束,可以在 deriveKeyIV
开头添加以下内容:
if (strlen($salt) != 8) {
throw new Exception('Salt must be 8 bytes long');
}