-3

I have been tasked with porting this code to Java:

define('SALT', 'my_salt');

function auth_encrypt($text){
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
 }

I have implemented this in Java as best I currently know how, but I'm neither an encryption nor a PHP maven (novice at best). Can someone help me figure out how to complete the following block so that that my output is the same in Java as theirs is in PHP?

byte[] sessionKey = Base64.encodeBase64("my_salt".getBytes());
byte[] iv = Base64.encodeBase64("WHAT-GOES-HERE??".getBytes());
byte[] plaintext = rawText.getBytes();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal(plaintext);
return new String(ciphertext, "UTF8");
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Howard Roark
  • 301
  • 1
  • 9
  • There may be a mistake in thinking that MCRYPT_RIJNDAEL_256 means a 256-bit key instead of the block size, I have seen this mistake before. – zaph Dec 18 '15 at 20:35
  • "Think twice" is, indeed, the start of what SO expects. Read the supporting documents in the introductory tour. Post your minimal code (perhaps with input), the failing result, and the result you want. Keep in mind that SO is not a coding or tutorial service; other sites handle those niches. – Prune Dec 18 '15 at 21:34

1 Answers1

3

ECB mode is not the same as CBC mode. Since ECB mode doesn't use an Initialization Vector (IV), you don't have to pass one to Cipher#init.

But this won't solve your problem, because MCRYPT_RIJNDAEL_256 is Rijndael with a block size of 256 bit, but AES is Rijndael with a block size of 128 bit. The default security provider doesn't usually provide Rijndael in Java, so you will have to use a non-standard provider such as BouncyCastle (Example).


Security considerations:

  • Never use ECB mode, because it's not semantically secure.
  • CBC mode provides semantic security, but only with an unpredictable (read random) IV. The IV doesn't have to be secret, so you can just prepend it to the ciphertext and slice off before decryption.
  • Authenticating your ciphertexts prevents many attacks. You can either use an authenticated mode like GCM or EAX, or apply an encrypt-then-MAC scheme with a strong MAC function like HMAC-SHA256.
Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Thanks. I have no control over what mode they used in PHP. And, the encryption that has to be done is for a legacy system where the implementation was not complete - this exercise is not at all about hiding values from the world, it's about making legacy systems work where people went down a road and didn't finish it. Nonetheless, I have zero control over any of it outside of the re-creation of it in Java. Thanks for the information. The example you pointed me to looks great. – Howard Roark Dec 18 '15 at 17:49
  • In that case, keep in mind that mcrypt uses "zero padding" by default, but it's probably not the same ZeroPadding as in Java. You should check if it works. Java might produce an additional block if the plaintext is a multiple of the block size. – Artjom B. Dec 18 '15 at 17:53