2

This is my code

 $key = pack('H*', "11223344556677881122334455667788");
 $plaintext = pack('H*', "0000000000000000");

 $ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $plaintext, MCRYPT_MODE_ECB);
 echo bin2hex($ciphertext);

but the result I got is 8ca64de9c1b123a7 was different from this site

6FB23EAD0534752B which is what I want

Can anyone explain why I get cypher text different from that site?

Thanh
  • 65
  • 2
  • 10
  • 1
    [According to this comment at php.net](http://php.net/manual/en/function.mcrypt-encrypt.php#47973), mcrypt's 3DES only accepts 192 bit keys. Your key is 128 bits. After `$key = pack('H*', "11223344556677881122334455667788");`, try adding `$key .= substr($key,0,8);` and see if that helps. (I'm unable to test as I don't have mcrypt installed anywhere.) – r3mainer May 18 '17 at 22:38
  • @squeamishossifrage Tested on Java, I got the result using key `112233445566778811223344556677880000000000000000`. mcrypt is certainly the most f*cked up library I ever came accross. – Maarten Bodewes May 18 '17 at 22:47
  • I try to encrypt in DES, and get right cypher text, but got PHP warning: Size of key is too large for this algorithm. So how this side does then? – Thanh May 18 '17 at 23:11

1 Answers1

2

mcrypt has - or rather had - the nasty habit of padding anything with zeros if the size isn't correct. Even worse, it also cuts keys to the correct size by removing bytes.

As squeamish ossifrage commented mcrypt only seems to support 3 key triple DES. That's not that bad, until you notice that it will happily accept a 2 key triple DES key of 16 bytes, and then pad it with zeros to make it a 3 key triple DES key. It should of course fail, and newer versions of mcrypt should actually do so.

You can create the same result using 3 key triple DES though. 2 key triple DES simply reuses the first key for the last key, so copying the first 8 bytes and appending it to the end of the key will get you the right result (again, as squeamish already noted).

Better use another crypto library to get right results. mcrypt (the underlying C library) hasn't been maintained for 8 years or so (and counting) and is crappy as hell.


Example in Java (which also doesn't support 2 key triple DES fully):

    byte[] pt = new byte[16];
    SecretKeyFactory fact = SecretKeyFactory.getInstance("DESede");
    Cipher desEDE = Cipher.getInstance("DESede/ECB/NoPadding");

    {
        // usual 2-key triple DES:
        byte[] keyData = Hex.decode("112233445566778811223344556677881122334455667788");
        SecretKey generatedSecret = fact.generateSecret(new SecretKeySpec(keyData, "DESede"));
        desEDE.init(Cipher.ENCRYPT_MODE, generatedSecret);
        byte[] ct = desEDE.doFinal(pt);
        System.out.println(Hex.toHexString(ct)); // result: 6FB23EAD0534752B 
    }

    {
        // "zero padded" 2-key triple DES:
        byte[] keyData = Hex.decode("112233445566778811223344556677880000000000000000");
        SecretKey generatedSecret = fact.generateSecret(new SecretKeySpec(keyData, "DESede"));
        desEDE.init(Cipher.ENCRYPT_MODE, generatedSecret);
        byte[] ct = desEDE.doFinal(pt);
        System.out.println(Hex.toHexString(ct)); // result: 8ca64de9c1b123a7 
    }

Notes:

  • your DES keys are not fully valid as the parity bits of each byte is not correctly set (those, however, are not used in the DES calculations);
  • better use AES and an authenticated cipher mode rather than the insecure ECB mode.
Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263