2

I have a php code that encrypts a plain text using rijndael algorithm in the EBC mode, and a 17-charachter key length. I'm looking to use an equivalent AES algorithm with Java

This is my php code:

<?php 
  $key=" 4288f0b8060ca1b "; 
  $mcryptAlgo= MCRYPT_RIJNDAEL_128 ; 
  $mcryptMode= MCRYPT_MODE_ECB ; 
  $data = "text_to_crypt_with_aes" ;

  $mcryptedData = mcrypt_encrypt ($mcryptAlgo, $key, $data, $mcryptMode); 
  $parametres_chiffres = urlencode( base64_encode ($mcryptedData)); 
  echo($parametres_chiffres);
?> 

It returns as a result the encrypted message: 4LepwOstJA0R2bg5FrdQXeoxesxmKV4pkf514F3VDqU%3D

However, the following Java code that I've built doesn't return the same message:

public static void main(String[] args) {

        StringBuilder sb = new StringBuilder();
        sb.append("text_to_crypt_with_aes");
        String clearText = sb.toString();
        StringBuilder sbKey = new StringBuilder(" 4288f0b8060ca1b ");
        for (int i = 0; i < 7; i++) {
            sbKey.append("\0");
        }

        try {

            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

            Key key = new SecretKeySpec(sbKey.toString().getBytes("UTF-8"),
                    "AES");

            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptedMessageInBytes = cipher.doFinal(clearText
                    .getBytes("UTF-8"));
            byte[] b64 = Base64.encodeBase64(encryptedMessageInBytes);
            String scrambled_text = new String(b64, Charset.forName("US-ASCII"));
            System.out.println(scrambled_text);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

It returns actually: 4LepwOstJA0R2bg5FrdQXRutIOZlJi06f0D8NnnIG5Q=

How can I adapt my Java code to return exactly the same as in php ?

  • Regarding which block cipher mode to choose I've written a description of each here: http://stackoverflow.com/a/22958889/371137 . I don't know if the key usage is representative for productive use later on, but if it is it is really weak and is close to being crackable by brute force alone with only 60bit of entropy. – Perseids Apr 24 '14 at 15:18

1 Answers1

3

The first 16 bytes are the same in both decryptions. The differences are in the last 16 bytes:

4LepwOstJA0R2bg5FrdQX eoxesxmKV4pkf514F3VDqU %3D
4LepwOstJA0R2bg5FrdQX RutIOZlJi06f0D8NnnIG5Q =

Since you are using ECB mode (don't, it is insecure) that tells me that you are encrypting the first block correctly and the second block is different. Your Java code specifies PKCS5 padding. PHP however uses zero padding to fill up the last block. The comments of mcrypt_encrypt contain examples to perform PKCS#7 padding, which is identical to PKCS#5 padding.

Community
  • 1
  • 1
rossum
  • 14,325
  • 1
  • 19
  • 34
  • mcrypt uses zero padding (fill up to block length with zero bytes) by default. It is as bad an idea as it sounds. I don't get, why the Java output is shorter than the PHP one, though. (@user25907) – Perseids Apr 24 '14 at 15:08
  • @Perseids They also cut down the key information if the keys don't fit. And if you look up the underlying c mcrypt libraries you will find out that those have been unmaintained since 2007 or so. – Maarten Bodewes Apr 24 '14 at 16:27
  • 1
    The Java is shorter because it has not replaced terminating "=" from the Base64 with the alternative rendering "%3D". That is merely a difference between the two systems. The underlying bit-pattern is the same, since the Base64 to bytes conversion won't be affected. ASCII 0x3D is an equals sign. – rossum Apr 24 '14 at 16:40
  • @owlstead: Apropos [related questions](http://stackoverflow.com/q/23280527/371137) ;-) – Perseids Apr 24 '14 at 21:52