Thursday, July 16, 2009

Flex As3crypto + php + rsa + openssl

Flex As3crypto + php + rsa + openssl
Well damn, all I wanted to do was encrypt a little data in my flex application upload it to php and decrypt it there. Of course that turns out to be incredibly complicated. So to all those who will come after me here’s an example of how I generated a 1024 bit RSA key pair with openssl, and used the public key to encrypt a phrase in flex, and the private key to decrypt the phrase in php. First a disclaimer though, I don’t know a lot about encryption or even a lot about what I’m doing but it seems to work and maybe you’ll find it useful.

PHP and openssl
If you want to play along you’re going to need php installed with openssl support. If you make a php file and put this in it:

and you scroll through the php info page and you don’t see this: Then you don’t have php and openssl working together, if you want to continue you’ll need to figure that out on your own. It’s not too hard though.

As3Crypto Build and Install
I’ll assume you’ve figured out your php and openssl configuration, so now it’s time to get the as3crypto library. DON’T JUST DOWNLOAD THE BINARY VERSION. I can’t stress that enough don’t just go to Hurlant’s website and get he latest binary version. Instead use svn to get the latest code base:

svn checkout as3crypto-read-only

If you don’t have svn or you don’t want to compile it yourself… you’ll be sad that you didn’t. Believe me I tried the easy way and it just didn’t work.

Once you get it downloaded get a command line or terminal window and go to the download directory. You can compile with this command:

compc -load-config=build-swc.xml

You’ll probably have to find out where your compc is located if it’s not in your path, and instead run something like:

/pathToCompC/compc –load-config=build-swc.xml

I also ran into the problem of it not knowing where playerglobal.swc was so I ended up editing that line in build-swc.xml to fit my installation. For me it was:


When you finally get it to compile it will put the file as3crypto.swc in the bin folder where you found build-swc.xml. Either leave that file there or copy it somewhere you like to keep these things.

Make yourself some keys
The next thing you’re going to want is a key pair. I made mine on my linux server using openssl. For me this is the same server I’m running php on. I’m sure there are a bunch of ways to generate the key pair but I followed the advice found here:

To make a private key just do:

openssl genrsa -out private.pem 1024

Then to extract the public key out of that private key do this:
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

Now you have two files private.pem, and public.pem that we’ll use in the next section.

Flex Code
All right enough BS here’s the code I used to encrypt a small phrase in my Flex-Air application.

            import com.hurlant.crypto.symmetric.ICipher;
            import com.hurlant.crypto.prng.Random;
            import com.hurlant.crypto.Crypto;
            //import com.hurlant.util.Base64;
            import mx.utils.Base64Encoder;
            import com.hurlant.util.Hex;
            import com.hurlant.util.der.PEM;
            import com.hurlant.crypto.rsa.RSAKey;

            private function sign():void
             var publicKey:String = "-----BEGIN PUBLIC KEY-----\n" +
                 "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIyrrhK7L1JQATG1zu/4ktyDdj\n" +
                 "Y41EIZxa5vUiq+ejUlQXNWmQZw8ATDGV2x/xJEcsZSbPqcxgyqDPQ8kGjQkv1kS/\n" +
                 "5ZP3oru5WSEypVPq1nfMCBoGTspyYIRpS+MjhhhN2X5y0NzR08kQQA81GRvBpmxM\n" +
                 "-----END PUBLIC KEY-----\n";

                //var rsa:RSAKey = RSAKey.parsePublicKey(getModulus(), exponent.text);
                var rsaPublicKey:RSAKey = PEM.readRSAPublicKey(publicKey);
                var data:ByteArray = new ByteArray;

                data.writeUTFBytes("fuck this crazy ass crap");
                var dst:ByteArray = new ByteArray;
                rsaPublicKey.encrypt(data, dst, data.length);
                var Enc64:Base64Encoder = new Base64Encoder;
                //use this on linux side to test
                //openssl rsautl -decrypt -inkey mykey.pem -in test.out -out decrypted.txt
                ///usr/bin/openssl enc -base64 -d -in test.64 -out test.out


The first thing you’ll notice is my public key that I got in the previous step. I have no idea if the \n’s are necessary but I put them there because I saw other people do that so monkey see monkey do.

Next I read the key into an RSAKey.

Then you make yourself a new Byte array to store the phrase you want to encrypt . In this example it’s called data.

Then you write the phrase into the byte array.

Now you make yourself another byte array called dst, this is where the encrypted data will go.

Next you base64 encode the data so you can easily copy and paste it. Base64 encoding just encodes all that encrypted data into normal text characters that you can safely drag around.

Finally you output that data with a trace so you can get it easily. For me the trace outputs:

XTLpqt9mNtyFchsjvFnffEplqaa+LHXCh52DpLi9CxvED4fUq5cWPuTX/1tHeG7deNBiGBiRW02r +LfW3JreVSkkc+sH6rq4ggKWi+1iPZoQd45f2VmwHVTvgC/IQX4eRuyFtSVoheHSLRL8zRO2/M27 K2jx49V+4JFVhtFAbQw=

This is your encrypted base64 encoded data, that we’ll decrypt in the next section.

PHP Time
I don’t know how you plan on getting your encrypted phrase to php, and frankly I don’t care. For me I just wanted to see it work so all I did was copy and paste. Here’s the PHP code I used to decrypt the phrase:

$privkey3 = "-----BEGIN RSA PRIVATE KEY-----

$result = openssl_pkey_get_private($privkey3);

if ($result)
        print "\nPrivate Key OK\n\n";
} else {
        print "\nPrivate key NOT OK\n\n";

$crypttext = "XTLpqt9mNtyFchsjvFnffEplqaa+LHXCh52DpLi9CxvED4fUq5cWPuTX/1tHeG7deNBiGBiRW02r

$crypttext = base64_decode($crypttext);

echo "
String decrypt : $newsource
"; while ($msg = openssl_error_string()) echo $msg . "

First you’ll see that I took the private key from the keys we made earlier and put it in this file. Make sure yours looks the same, if you paste your private key without the right new lines it won’t work. At least it didn’t for me so must make sure you format it like you see in the code.

Next we call openssl_pkey_get_private on that private key.

Now you’ll see the encrypted phrase from our Air application in the $crypttext variable.

We base64 decode that to get back to the raw data.

Then we run it through openssl_private_decrypt to decrypt the data.

Finally we just output the data to the screen.

That last little while loop will output any openssl errors that might have occurred, and can be at least a little useful in debugging.

The End
Well I hope that helps someone else who comes along and tries to do the same thing. It was a pain in the ass to figure this all out especially because as3crypto has no documentation. I’m not knocking it though I mean you just got a completely free cryptography library for your flash project right.

One last thing if you, like me, know about as much about cryptography as you do about how to win the lottery, then you may be disappointed to find out you can only use RSA to encrypt a relatively small amount of data (it’s dependant on your key size). So most people use this to either exchange keys, or make a hash of what they’re sending and encrypt that.

Of course if you happen to know a lot about how to win the lottery... drop me an email with some tips.