Home  >  Q&A  >  body text

How to decrypt encrypted string in Java in PHP?

<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>
P粉083785014P粉083785014437 days ago539

reply all(1)I'll reply

  • P粉014218124

    P粉0142181242023-08-31 10:27:11

    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 follows build3DesKey():

    $key = substr(str_pad($key, 24, "
    $key = "12345";
    $ciphertext = "84b24172c57752385251d142abadbed1d9945301a3aee429ce00c1e291a605c30ad18c5e00007f6db394fc6138a2ee4c";
    $key = substr(str_pad($key, 24, "rrreee"), 0, 24);
    $plaintext = openssl_decrypt(hex2bin($ciphertext), "des-ede3", $key, OPENSSL_RAW_DATA);
    print($plaintext. PHP_EOL); // The quick brown fox jumps over the lazy dog
    
    "), 0, 24);

    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 to str2ByteArray() is hex2bin().

    So a possible implementation of decryption is (using PHP/OpenSSL):

    rrreee

    These 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:

    • Key derivation 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.
    • des-ede3 applies ECB mode, which is also unsafe. Authenticated encryption such as AES-GCM should now be used.
    • 3DES/TripleDES is obsolete, and the only variant not yet deprecated, Triple Length Key or 3TDEA, will also be deprecated soon and is relatively slow. Today's standard is to apply AES.

    reply
    0
  • Cancelreply