Mohit Mehral
Mohit Mehral

Reputation: 307

Alternative to PHP Encryption in Java

I am having a PHP which is working fine and I want to replicate the same and want to do it using java. My PHP code uses MCRYPT_RIJNDAEL_256 :

 $iv = "42309842389462374623784692423642";
   $key = "asfuyjkdhfabcdef";
   $text = "0007";    

  $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
  $padding = $block - (strlen($text) % $block);
  $text .= str_repeat(chr($padding), $padding);
  $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
  $crypttext64=base64_encode($crypttext);

  echo $crypttext64;

which returns: KdL2lWUGqy+UqLxbe9VTS6OCgvnJFn1jtMCgkj1434A=

But while encrypting using java :

  byte[] sessionKey = "asfuyjkdhfabcdef".getBytes(Charset.forName("ASCII"));

  byte[] iv = "42309842389462374623784692423642".getBytes(Charset.forName("ASCII"));

            String plaintext="0007";

            String data = new String(new char[28]).replace("\0", Character.toString ((char) 28));

            String newdata = plaintext+data;
            newdata = newdata.substring(0,32);
            byte [] dataBytes = newdata.getBytes(Charset.forName("ASCII"));
            System.out.println(dataBytes);

            PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
                new CBCBlockCipher(new RijndaelEngine(256)),new PKCS7Padding());



            cipher.init(true, new ParametersWithIV(new KeyParameter(sessionKey), iv));


            byte[] encrypted  = new byte[cipher.getOutputSize(dataBytes.length)];

            int oLen = cipher.processBytes(dataBytes, 0, dataBytes.length, encrypted, 0);
            cipher.doFinal(encrypted, oLen);   
             String s = new String(encrypted);
            System.out.println(Base64.getEncoder().encodeToString(s.getBytes()));

I am getting below output:

KdL2lWUGqy+UqLxbe9VTS6OCgvnJFn1jtMCgkj1434DMpLehN7ve0AhnMOQtT1fLcZIUfM9rF/iVOKj6UtgwyA==

Both the outputs are different. Please suggest the way so that I can get the same output in JAVA also.

Upvotes: 1

Views: 217

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94018

You seem to try and perform the padding twice:

String data = new String(new char[28]).replace("\0", Character.toString ((char) 28));

String newdata = plaintext+data;
newdata = newdata.substring(0,32);
byte [] dataBytes = newdata.getBytes(Charset.forName("ASCII"));
System.out.println(dataBytes);

seems to be an ill written attempt to perform the PKCS#7 padding, which you already do in your code (new PKCS7Padding()).

Just replace it by:

plaintext.getBytes(StandardCharsets.US_ASCII)

As you can see, the first part of the base 64 is identical in both PHP and Java. Note that PHP doesn't contain PKCS#7 padding, which is why this was coded using str_repeat.


Furthermore the encrypted array should be directly put into the encodeToString method, first converting to String and then back to byte[] again can only loose data. So strip out s in the following code:

String s = new String(encrypted);
System.out.println(Base64.getEncoder().encodeToString(s.getBytes()));

Upvotes: 2

Related Questions