PHP Equivalent for Java Triple DES encryption/decryption

前端 未结 2 1983
抹茶落季
抹茶落季 2020-12-09 23:30

Am trying to decrypt a key encrypted by Java Triple DES function using PHP mcrypt function but with no luck. Find below the java code

import javax.crypto.Cip         


        
相关标签:
2条回答
  • 2020-12-09 23:50

    This is the PHP equivalent of your Java code (I have copied the PKCS#5-padding from the comment 20-Sep-2006 07:56 of The mcrypt reference)

    function encryptText($plainText, $key) {
        $keyData = "\xA2\x15\x37\x08\xCA\x62\xC1\xD2"
            . "\xF7\xF1\x93\xDF\xD2\x15\x4F\x79\x06"
            . "\x67\x7A\x82\x94\x16\x32\x95";
    
        $padded = pkcs5_pad($plainText,
            mcrypt_get_block_size("tripledes", "cbc"));
    
        $encText = mcrypt_encrypt("tripledes", $keyData, $padded, "cbc", $key);
    
        return base64_encode($encText);
    }
    
    function decryptText($encryptText, $key) {
        $keyData = "\xA2\x15\x37\x08\xCA\x62\xC1\xD2"
            . "\xF7\xF1\x93\xDF\xD2\x15\x4F\x79\x06"
            . "\x67\x7A\x82\x94\x16\x32\x95";
    
        $cipherText = base64_decode($encryptText);
    
        $res = mcrypt_decrypt("tripledes", $keyData, $cipherText, "cbc", $key);
    
        $resUnpadded = pkcs5_unpad($res);
    
        return $resUnpadded;
    }
    
    
    function pkcs5_pad ($text, $blocksize)
    {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }
    
    function pkcs5_unpad($text)
    {
        $pad = ord($text{strlen($text)-1});
        if ($pad > strlen($text)) return false;
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
        return substr($text, 0, -1 * $pad);
    }
    

    But there are some problems you should be aware of:

    • In your Java code you call String.getBytes() without indicating an encoding. This makes your code non portable if your clear text contains non ASCII-characters such as umlauts, because Java uses the system-default character set. If you can change that I certainly would do so. I recommend you to use utf-8 on both sides (Java and PHP).
    • You have hard coded the cipher-key and use the IV as "key". I'm by no means a crypto-expert but to me it just feels wrong and may open a huge security leak.
    • Create a random IV and just concatenate it at the start or at the end of your message. Since the size of the IV is AFAIK equal to the block-size of your cipher you just remove that much bytes from the start or end and have easily separated the IV from the message.
    • As for the key, it's best to use some kind of key derivation method to generate a key with the right size from a "human generated" password.

    Of course, if you have to fulfil some given requirements you can't change your method.

    0 讨论(0)
  • 2020-12-10 00:03

    The answer is almost good! Just reverse $keyData and $key in

    $encText = mcrypt_encrypt("tripledes", $keyData, $padded, "cbc", $key);
    

    and

    $res = mcrypt_decrypt("tripledes", $keyData, $cipherText, "cbc", $key);
    

    otherwise you will always use the same 3DES key. And it's better to rename $keyData to $iv.

    Anyway, thanks a lot for the Java sample and the Php-Java translation.

    0 讨论(0)
提交回复
热议问题