PBEWithMD5AndTripleDES uses an MD5 based algorithm for key / IV derivation, which expects a password, a salt and an iteration count as parameters. For encryption TripleDES in CBC mode (des-ede3-cbc
) with a 24 bytes key is applied.
PBEWithMD5AndTripleDES is an Oracle proprietary extension of the password-based encryption defined in PKCS#5 (RFC 8018) to support longer keys, here. Because it is proprietary and because of the outdated algorithms like MD5 and the relatively slow TripleDES compared to AES, it should not be used for new implementations, but only for compatibility with legacy code.
I have not found any PHP library on the web that supports PBEWithMD5AndTripleDES out-of-the-box (only for the different PBEWithMD5AndDES, e.g. 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 is a Java code that implements the derivation. A port to PHP could be:
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;
}
The function returns 32 bytes, of which the first 24 bytes are the key and the last 8 bytes are the IV. With this key and IV the encryption with TripleDES in CBC mode can then be performed.
Example:
$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));
Output:
543650085edbbd6c26149c53a57cdd85871fd91c0f6d0be4
d7ffaa69502309ab
m4pye0texirKz1OeKqyKRJ5fSgWcpIPEhSok1SBDzgPthsw9XUuoiqXQBPdsVdUr
As reference I used a Java implementation, more precisely the implementation of PBEWithMD5AndTripleDES of the SunJCE provider, which gives the same result.
Note that the original implementation of PBEWithMD5AndTripleDES only allows a salt that is exactly 8 bytes in size (although the derivation function can handle larger salts), otherwise an exception is thrown (salt must be 8 bytes long). To add this constraint, the following can be added at the beginning of deriveKeyIV
:
if (strlen($salt) != 8) {
throw new Exception('Salt must be 8 bytes long');
}