PHP DES-ECB encryption docking Java decryption

Recently, the company has a business that needs to connect to the third-party interface, but the parameters need to be encrypted. The other side only provides a java demo and searches all over the Internet. No direct method can be found. Later, it was connected with the company's Android Engineer. Here's a record of the general process.
First, the interface request mode required by the other party is described. The format is: http://ip : port/interface/method?data = summary @ hexadecimal string
Explain:

1. The request parameters need to be combined into a parameter string of a = 1 & B = 2 & C = 3 format;
2. The generation method of abstract is MD5 ('a = 1 & B = 2 & C = 3 ');
3. The method of generating hexadecimal string is to encrypt the parameter string with * * symmetric encryption (DES-ECB) * * and then convert it to hexadecimal string (bin2hex function);

The demo(java version) provided by the other party is as follows:

public class DesUtils {

    /** Default key */
    private static String strDefaultKey = "seeyonssokey";

    /** encryption tool */
    private Cipher encryptCipher;

    /** Decryption tool */
    private Cipher decryptCipher;

    /**
     * Encrypted string
     * @param strIn String to encrypt
     * @return Encrypted string
     * @throws Exception
     */
    public String encrypt(String strIn) throws Exception {
        return byteArr2HexStr(encryptCipher.doFinal(strIn.getBytes()));
    }

    /**
     * Decrypt string
     * @param strIn String to decrypt
     * @return Decrypted string
     * @throws Exception
     */
    public String decrypt(String strIn) throws Exception {
        return new String(decryptCipher.doFinal(hexStr2ByteArr(strIn)));
    }

    /**
     * Convert byte arrays to strings representing hexadecimal values, such as: byte[]{8,18} to: 0813, and public static
     * byte[] hexStr2ByteArr(String strIn) Mutually reversible conversion process
     * @param arrB byte array to convert
     * @return Converted String
     * @throws Exception This method does not handle any exceptions, all exceptions are thrown
     */
    public static String byteArr2HexStr(byte[] arrB) throws Exception {
        int iLen = arrB.length;
        // Each byte is represented by two characters, so the length of the string is twice the length of the array
        StringBuffer sb = new StringBuffer(iLen * 2);
        for(int i = 0; i < iLen; i++) {
            int intTmp = arrB[i];
            // Convert a negative number to a positive number
            while(intTmp < 0) {
                intTmp = intTmp + 256;
            }
            // Numbers less than 0F need to be filled with 0 in front
            if(intTmp < 16) {
                sb.append("0");
            }
            sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
    }

    /**
     * Converts a string representing a hexadecimal value to a byte array, and public static String
     * byteArr2HexStr(byte[] arrB) Mutually reversible conversion process
     * @param strIn String to be converted
     * @return Converted byte array
     * @throws Exception This method does not handle any exceptions, all exceptions are thrown
     * @author <a href="mailto:leo841001@163.com">LiGuoQing</a>
     */
    public static byte[] hexStr2ByteArr(String strIn) throws Exception {
        byte[] arrB = strIn.getBytes();
        int iLen = arrB.length;
        // Two characters represent a byte, so byte array length is string length divided by 2
        byte[] arrOut = new byte[iLen / 2];
        for(int i = 0; i < iLen; i = i + 2) {
            String strTmp = new String(arrB, i, 2);
            arrOut[i / 2] = (byte)Integer.parseInt(strTmp, 16);
        }
        return arrOut;
    }

    /**
     * The key is generated from the specified string. If the length of byte array required for the key is less than 8 bits, then 0 will be filled. If the length is more than 8 bits, only the first 8 bits will be taken
     * @param arrBTmp An array of bytes that make up the string
     * @return Generated key
     * @throws java.lang.Exception
     */
    private static Key getKey(byte[] arrBTmp) throws Exception {
        // Create an empty 8-bit byte array (default 0)
        byte[] arrB = new byte[8];
        // Convert original byte array to 8 bits
        for(int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
            arrB[i] = arrBTmp[i];
        }
        // Generating key
        Key key = new SecretKeySpec(arrB, "DES");
        return key;
    }

    public static String encrypt(String strIn, String secretkey) throws Exception {
        Key key = getKey(secretkey.getBytes("utf-8"));
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return byteArr2HexStr(cipher.doFinal(strIn.getBytes("utf-8")));
    }

    public static String decrypt(String strIn, String secretkey) throws Exception {
        Key key = getKey(secretkey.getBytes("utf-8"));
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] param = cipher.doFinal(hexStr2ByteArr(strIn));
        return new String(param, "utf-8");
    }
}

There are two ways to implement the encryption function in PHP:

  • mcrypt mode (for versions prior to php7.0):
<?php

$text = 'a=1&b=2&c=3';  //Parameter string
$key = 'abcd1234';      // secret key
echo $ret = self::encryptForDES($text , $key);  //encryption

/**
 * String encryption (encryption method: DES-ECB)
 * @param string $input String to be encrypted
 * @param string $key Symmetric encryption key
 * @return string
 */
function encryptData($input, $key)
{
    $size = mcrypt_get_block_size('des','ecb'); // Calculate the packet size of encryption algorithm
    $input = self::pkcs5_pad($input, $size);    // Complement a string
    $td = mcrypt_module_open('des', '', 'ecb', '');

    $iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);

    @mcrypt_generic_init($td, $key, $iv);
    $data = mcrypt_generic($td, $input);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    $data = bin2hex($data); // Convert encrypted string to hexadecimal
    return $data;
}

/**
 - Complement a string
 - @param string $text Original string
 - @param string $blockSize Packet size of encryption algorithm
 - @return string
 */
function pkcs5_pad($text, $blockSize)
{
    $pad = $blockSize - (strlen($text) % $blockSize);
    return $text . str_repeat(chr($pad), $pad);
}

Output: 990389f0aad8d12014ca6a45cd72cdf7

  • openssl mode (for versions later than php7.0):
<?php

$text = 'a=1&b=2&c=3';            // Parameter string
$key = 'abcd1234';                // secret key
echo encryptData($text, $key);    // encryption

/**
 * String encryption (encryption method: DES-ECB)
 * @param string $input String to be encrypted
 * @param string $key Symmetric encryption key
 * @return string
 */
function encryptData($input, $key)
{
    $ivlen = openssl_cipher_iv_length('DES-ECB');    // Get password iv length
    $iv = openssl_random_pseudo_bytes($ivlen);        // Generate a pseudo-random byte string
    $data = openssl_encrypt($input, 'DES-ECB', $key, $options=OPENSSL_RAW_DATA, $iv);    // encryption
    return bin2hex($data);
}

Output: 990389f0aad8d12014ca6a45cd72cdf7

Keywords: Java PHP less Android

Added by tcorbeil on Wed, 11 Dec 2019 23:00:29 +0200