AES Interop Between PHP and Java (Part 2)
… Give him a fish; you fed him for today. Teach him how to fish; you fed him for life …
The Problem: In a previous post, I show how to use AES in PHP to encrypt a message and decrypt it in Java. Then Amit asked if it could be done the other way around.
Again, without all the knowledge about AES, Key, CBC, ECB, etc, etc… I will present a simple solution. Keep in mind, these are bits and pieces, so that I wouldn’t take all the fun out of you. I will just show you how to encrypt and decrypt and you can implement other things in between so that you can also have the fun.
The Solution:
- Encrypt a message in Java:
001 import javax.crypto.*; 002 import javax.crypto.spec.*; 003 import java.security.*; 004 import java.io.*; 005 006 public class tester { 007 public static String bytesToHex(byte[] data) { 008 if (data==null) { 009 return null; 010 } else { 011 int len = data.length; 012 String str = ""; 013 for (int i=0; i<len; i++) { 014 if ((data[i]&0xFF)<16) 015 str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF); 016 else 017 str = str + java.lang.Integer.toHexString(data[i]&0xFF); 018 } 019 return str; 020 } 021 022 public static void main(String[] args) throws Exception { 023 String plaintext = "Hello World "; 024 String key = "01234567890abcde"; 025 String iv = "fedcba9876543210"; 026 027 SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); 028 IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); 029 030 Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 031 cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec); 032 byte[] encrypted = cipher.doFinal(plaintext.getBytes()); 033 034 System.out.println("Encrypted: " + bytesToHex(encrypted)); 035 036 cipher.init(Cipher.DECRYPT_MODE,keyspec,ivspec); 037 byte[] decrypted = cipher.doFinal(encrypted); 038 System.out.println(new String(decrypted)); 039 } 040 } - The output of the Java program should be “444e6969a269829a3e59a86300614fc5″. Take note that I cheated by making the plain text message as “Hello World ” (16 bytes). You can work out the padding part of Java program (or someone is nice enough to put it in the comment).
- We just take the output and decrypt it over in the following PHP program:
001 <?php 002 function hex2bin($hexdata) { 003 $bindata=""; 004 005 for ($i=0;$i<strlen($hexdata);$i+=2) { 006 $bindata.=chr(hexdec(substr($hexdata,$i,2))); 007 } 008 009 return $bindata; 010 } 011 012 $cipher = "rijndael-128"; 013 $mode = "cbc"; 014 $secret_key = "01234567890abcde"; 015 $iv = "fedcba9876543210"; 016 017 $td = mcrypt_module_open($cipher, "", $mode, $iv); 018 019 mcrypt_generic_init($td, $secret_key, $iv); 020 $decrypted_text = mdecrypt_generic($td, hex2bin("444e6969a269829a3e59a86300614fc5")); 021 echo trim($decrypted_text); 022 mcrypt_generic_deinit($td); 023 mcrypt_module_close($td); 024 ?> - The output should be “Hello World”.
March 20th, 2007 at 10:32 am
Just for your information, there is a blog to show how to Encrypt in PHP and Decrypt in Java here http://www.propaso.com/blog/2007/01/27/aes-interop-between-php-and-java/
March 23rd, 2007 at 12:05 pm
Your script makes me shimmer with desire, except that you don’t indicate where to find or what is in the includes:
import javax.crypto.*;
002 import javax.crypto.spec.*;
003 import java.security.*;
004 import java.io.*;
“So hot right now”
March 23rd, 2007 at 12:08 pm
Nevermind. I see that you’re going from Java to PHP, not Javascript. How typical of a tyrannical leader like myself to make such a mistake.
March 23rd, 2007 at 12:18 pm
Hi Valerian,
It would be really nice if you have a JavaScript version of AES encryption/decryption that you might want to share it here. If not I might get myself to do it if I am feeling not that lazy.
April 13th, 2007 at 4:04 pm
> You can work out the padding part of Java program (or someone is nice enough to put it in > the comment
This example covers exactly what I’m looking for except that I need to be able to encrypt a string that varies greatly in length (a.k.a. no cheating with 16 byte strings). Could someone post a modified version of the example above (both sides: java & php) that can handle this? Thanks in advance!
June 19th, 2007 at 4:39 am
I have the same problem. I need to encrypt in java and decript in php…(without hacking)
How do this?
Thanks
June 19th, 2007 at 6:18 am
Hello,
I have wrote a quick patch for padding the characters since there are two request for it and no one had put it in yet. First, add the following function to the program:
public static String padString(String source, char paddingChar, int size) {
int padLength = size-source.length()%size;
for (int i = 0; i < padLength; i++) {
source += paddingChar;
}
return source;
}
then change line 023 in the Java program from:
String plaintext = “Hello World “;
to
String plaintext = padString(”Hello World”, ‘ ‘, 16);
that should do the trick. (take note that the second parameter is a space ‘ ‘).
June 21st, 2007 at 7:38 am
Hey everybody,
Writing a cipher in Javascript is *not* something you want to do because it violates rule #1 of encryption: NEVER give anyone they Key.
In a javascript implementation you give everyone they key, because javascript is run on the client’s machine.
I’ve recently written a PHP AES class that is 100% FIPS 197 compliant. You could use it to cipher between PHP and any other language, and best of all it doesn’t require any pre-complied libraries for PHP.
Check it out at http://www.phpaes.com/ *** This is not free code **Admin**
E-mail me with any questions: cody [at] wshost [dawt] net
June 21st, 2007 at 6:50 pm
Hi Cody,
It is possible to use an external JavaScript file using something like:
However, I am not a guru in JavaScript (or even in PHP or Java), so I not able to advise how secure an external JavaScript is. Sorry that I have to comment on your URL to let others know that it is not free.
July 12th, 2007 at 7:22 am
Linus,
You cannot put the key in the internal Javascript file like your example above, because, just as the Client browser calls that file with an HTTP GET request, so can anyone else. For example, :
Your Domain : http://www.somedomain.com
your program : my.js (called as a include in say index.html
then I could type : http://www.somedomain.com/my.js
and read the entire javascript file as text in my browser !!!
the only only way you can do this in JS is NEVER (unless you use AJAX (php + xml/rpc)
July 17th, 2007 at 1:25 pm
There are times where it is absolutely appropriate to say thank you for a great how-to. Thank you for this post. It fit like a puzzle piece into a project I was working on and simply did not want to look into all the api’s for php for the aes encryption (much less CBC!!!). I have the front and back end built in java (jsp).. thank you again!
July 17th, 2007 at 7:02 pm
Hi,
I use mcrypt to store some passwords in a db.
Now i want to decrpyt those pw on the client side. I really don’t know anything about java.
Is this a java-applet which can be run from a browser? How would I compile it. I googled a little bit, but am not sure what to google for really.
Any suggestions on any (simple) java starting howto would be nice.
Any applets i can use would be even better…
I hope anybody can point me in the right direction.
Thankx
July 17th, 2007 at 8:05 pm
Hi Heiner,
You can actually decrypt it in PHP, if there is no requirement to use Java. However, if you are interested in using Applet, you can start by looking at http://www.realapplets.com/tutorial/HelloWorld.html
July 18th, 2007 at 11:32 pm
Hi linus,
I know that I can decrypt in PHP. I already realized an application that en-/decrypts. I found this blog when I searched for a possibility to decrypt the passwords on the client side.
If that is somehow possible (I don’t even know if the java-source, which is posted here, can be executed at the client end) I would not have to think about a ssl-encryption for my little script.
Even with a ssl-encryption I would rather send the data encrypted to the client and then locally decrypt it.
Thx for the reply and I hope for more…
July 19th, 2007 at 12:10 am
OK, when I compile the source from PART 1 and try to run it my java console throws this errors:
java.lang.ClassCastException: tester cannot be cast to java.applet.Applet
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.plugin.AppletViewer.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.ClassCastException: tester cannot be cast to java.applet.Applet
at sun.applet.AppletPanel.createApplet(Unknown Source)
at sun.plugin.AppletViewer.createApplet(Unknown Source)
at sun.applet.AppletPanel.runLoader(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
What did I do wrong?
The HelloWorld example from the posted website from linus did work fine…
September 25th, 2007 at 11:48 pm
Thank you for these examples. Wanted to let you know that the links from php.net/mcrypt do not work anymore.
Part 1 - Encrypt Using PHP / Decrypt Using Java
http://www.propaso.com/blog/2007/01/27/aes-interop-between-php-and-java/
Part 2 - Encrypt Using Java / Decrypt Using PHP
http://www.propaso.com/blog/2007/03/12/aes-interop-between-php-and-java
-part-2-working-the-other-way-around/
October 6th, 2007 at 10:54 am
Hi Audrey,
Thanks for informing me, I will update the php.net soon.
October 6th, 2007 at 11:11 am
[…] Things in Life What’s Life without Fun? « AES Interop Between PHP and Java (Part 2) AES Interop Between PHP and Java (Part 4) […]
July 24th, 2008 at 4:00 pm
Hi there, I was looking around for a while searching for aes encryption and I happened upon this site and your post regarding AES Interop Between PHP and Java (Part 2), I will definitely this to my aes encryption bookmarks!
February 17th, 2009 at 5:04 pm
thanks for this! my php host doesn’t have mcrypt installed, unfortunately, so i went around looking for libraries that didn’t require it.
there’s http://www.phpaes.com/ as mentioned above but that’s not free. here’s one that is:
http://phpseclib.sourceforge.net/documentation/crypt.html#crypt_aes_benchmarks
LGPL licensed and 11x faster than the one at http://www.phpaes.com/. uses mcrypt if available, php otherwise.
February 26th, 2009 at 11:04 am
great tutorial
thanks
April 28th, 2009 at 7:24 pm
MCRYPT CBC Interoperability seems fine.
But MCRYPT OFB Does not match !!! with others implementations.
What is wrong with OFB ?
May 22nd, 2009 at 3:33 am
Hi ndeh,
I have never tried OFB. As I am not really an expert in encryption. I will try to understand more.
July 1st, 2009 at 6:18 am
First of all, I’d like to saya BIG THANK YOU for this blog! You saved me a lot of time and effort!!!
I did face a little trouble compiling the php code you provided though. The error involved something to do with an incorrect IV size. So, i replaced the IV with “” and then added an extra line. It works well like this:
$td = mcrypt_module_open(”rijndael-128″, “”, “cbc”, “”);
mcrypt_generic_init($td, $key, $iv);
Hope this will helpful to someone. Thanks again!!!