0

I have a DES Algorithm use java ,now I need convert this java program for php, I don't know java cipher.init method's third parameters SecureRandom ,So I use my php Des program to encrypt a string ,but I got a different result with java Des.

Here is my Java DES:

public static String encode(String srcStr) {
    if (srcStr == null)
        return null;
    String dst = null;
    byte[] result = encrypt2(srcStr.getBytes(), "h43au76U");
    if (result == null)
        return null;
    System.out.println(result);
    dst = byte2HexStr(result, result.length);
    return dst;
    }

 private static final char[] mChars = "0123456789ABCDEF".toCharArray();


 public static String byte2HexStr(byte[] b, int iLen) {
        if (b == null)
            return null;
        StringBuilder sb = new StringBuilder();
        for (int n = 0; n < iLen; n++) {
            sb.append(mChars[(b[n] & 0xff) >> 4]);
            sb.append(mChars[b[n] & 0xf]);
        }
        return sb.toString().trim().toUpperCase(Locale.US);
        }



 private static byte[] encrypt2(byte[] datasource, String password) {
        byte[] is;
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes("UTF-8"));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            javax.crypto.SecretKey securekey
            = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(1, securekey, random);
            is = cipher.doFinal(datasource);
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
        return is;
        }

And this is my php des:

function encrypt($input,$key,$iv=0){
    $size = mcrypt_get_block_size(MCRYPT_DES,MCRYPT_MODE_CBC); //3DES加密将MCRYPT_DES改为MCRYPT_3DES
    $input =pkcs5_pad($input, $size); //如果采用PaddingPKCS7,请更换成PaddingPKCS7方法。
    $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
    @mcrypt_generic_init($td, $key,$iv);
    $data = mcrypt_generic($td, $input);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
//    return $data;
   return strtoupper(bin2hex($data));
}

I got a different result, why? And I don't know if SecureRandom is a iv ?

1
  • DES is no longer considered secure and should not be used, use AES instead–if you are interested in security. It is best not to use mcrypt, it is abandonware, has not been updated in years and does not support standard PKCS#7 (née PKCS#5) padding, only non-standard null padding that can't even be used with binary data. mcrypt had many outstanding bugs dating back to 2003. Instead consider using defuse, it is being maintained and is correct. Commented Jun 20, 2016 at 12:53

2 Answers 2

2

Always use a fully qualified Cipher string. Cipher.getInstance("DES"); may result in different ciphers depending on the default security provider. It most likely results in "DES/ECB/PKCS5Padding", but it doesn't have to be. If it changes, you'll lose compatibility between different JVMs.

What you need to do in PHP to achieve compatibility with Java is to use ECB mode instead of CBC mode and apply PKCS#5 padding (same as PKCS#7 padding). This answer shows an implementation of that padding. You just have to use the correct block size which is 8 for DES.


Never use ECB mode. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like CBC or CTR. It is better to authenticate your ciphertexts so that attacks like a padding oracle attack are not possible. This can be done with authenticated modes like GCM or EAX, or with an encrypt-then-MAC scheme.

The IV must be unpredictable (read: random). Don't use a static IV, because that makes the cipher deterministic and therefore not semantically secure. An attacker who observes ciphertexts can determine when the same message prefix was sent before. The IV is not secret, so you can send it along with the ciphertext. Usually, it is simply prepended to the ciphertext and sliced off before decryption.

Sign up to request clarification or add additional context in comments.

Comments

0
public static function encryptDes($data, $key)
{
     $paddedData = static::pad($data);
     $opts = OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA;
     return strtoupper(bin2hex(openssl_encrypt($paddedData, 'DES-ECB', $key, $opts)));
}

public static function decryptDes($data, $key)
{
    $data = hex2bin($data);
    $opts = OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA;
    return static::unpad(openssl_decrypt($data, 'DES-ECB', $key, $opts));
}

private static function pad($text)
{
    $blockSize = 8;
    $length = strlen($text);
    $pad = $blockSize - ($length % $blockSize);
    return str_pad($text, $length + $pad, chr($pad));
}

private static function unpad($text)
{
    $length = ord($text[strlen($text) - 1]);
    return substr($text, 0, -$length);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.