How to decrypt encrypted string in Java in PHP?
P粉083785014
2023-08-30 12:12:13
<p>I am trying to decrypt an encrypted string in JAVA using the following code. </p>
<pre class="lang-java prettyprint-override"><code>SecretKey secretKey = new SecretKeySpec(build3DesKey(key), "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] b = cipher.doFinal(str2ByteArray(dest));
String decoder = new String(b, "utf-8");
</code></pre>
<pre class="lang-java prettyprint-override"><code>private static byte[] build3DesKey(String keyStr) throws Exception {
byte[] key = new byte[24];
byte[] temp = keyStr.getBytes("utf-8");
if (key.length > temp.length) {
System.arraycopy(temp, 0, key, 0, temp.length);
} else {
System.arraycopy(temp, 0, key, 0, key.length);
}
return key;
}
</code></pre>
<p>How do I get the same results in the PHP version? I tried writing it in PHP, but the output was wrong. </p>
<pre class="brush:php;toolbar:false;">$data = '69C16E8142F2BDDE7569842BB0D68A3176624264E...';
$key = 'rpwdvbppnrvr56m123 #';
function decrypt($data, $secret)
{
//generate key from hash
$key = md5(utf8_encode($secret), true);
//Append the first 8 bytes of $key to the end of $key.
$key .= substr($key, 0, 8);
$data = base64_decode($data);
$data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
$block = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = ord($data[$len-1]);
return substr($data, 0, strlen($data) - $pad);
}
var_dump(utf8_encode(Decrypt($data, $key)));</pre></p>
Function
build3DesKey()
Extends a too short 3DES key to 24 bytes by padding the end with a 0x00 value, for too long keys the end is simply truncated. In PHP, it can be implemented as followsbuild3DesKey()
:Although the function
str2ByteArray()
is missing, its functionality can be inferred. Since in your example the ciphertext is hex encoded, this function seems to just perform hex decoding. In PHP, the counterpart tostr2ByteArray()
ishex2bin()
.So a possible implementation of decryption is (using PHP/OpenSSL):
rrreeeThese input data return the same plaintext in Java code!
Differences from your code:
Your code uses the deprecated
mcrypt
. For security reasons, it should not be used now. A better alternative is PHP/OpenSSL, as shown in the code above. Furthermore, the implemented key derivation is wrong, e.g. it applies MD5 digest, which is not used at all in the Java code.safety:
Although this may be an old app, a few notes on security:
build3DesKey()
is unsafe. If the key material is a string, it is usually not a key but a password. Therefore, a reliable key derivation function such as Argon2 or PBKDF2 should be used.