as3Crypto and php, what a fun ride!

Actually not so fun, but I did manage (I should say we because I wasn’t alone in this). Cryptography is not my thing, eh, not everything can be your thing so I accept it. There is just too much to learn: hash functions, public keys, symmetric ciphers, etc. Want we wanted to do was to encrypt data on the As3 side and decrypt it on the php side. I was aware that there was some cryptographic algorythms in the as3corelib, but none of them (MD5, SHA-1) fitted our needs. There is another great cryptography library out there and it is as3Crypto; the problem is that it is a bit hard to get around, there is a lot to choose from. We settled on AES (Advanced Encryption Standard). After 2 hours of trying to get it to work, we found this great post on Google groups (about middle of the page). I am copying the content here to make it easier for people to find. I have to give all the credit for this post to Jason Foglia who posted his code.

Here is the As3 Class:

 
package
{
        import flash.display.Sprite;
        import flash.utils.ByteArray;
 
        import com.hurlant.crypto.symmetric.ICipher;
        import com.hurlant.crypto.symmetric.IVMode;
        import com.hurlant.crypto.symmetric.IMode;
        import com.hurlant.crypto.symmetric.NullPad;
        import com.hurlant.crypto.symmetric.PKCS5;
        import com.hurlant.crypto.symmetric.IPad;
        import com.hurlant.util.Base64;
        import com.hurlant.util.Hex;
        import com.hurlant.crypto.Crypto;
 
        public class CryptoCode extends Sprite
        {
                private var type:String='simple-des-ecb';
                private var key:ByteArray;
 
                public function CryptoCode()
                {
                        init();
                }
 
                private function init():void
                {
                        key = Hex.toArray(Hex.fromString('TESTTEST'));// can only be 8 characters long
 
                        trace(encrypt('TEST TEST'));
                        trace(decrypt(encrypt('TEST TEST'));
                }
 
                private function encrypt(txt:String = ''):String
                {
                        var data:ByteArray = Hex.toArray(Hex.fromString(txt));
 
                        var pad:IPad = new PKCS5;
                        var mode:ICipher = Crypto.getCipher(type, key, pad);
                        pad.setBlockSize(mode.getBlockSize());
                        mode.encrypt(data);
                        return Base64.encodeByteArray(data);
                }
                private function decrypt(txt:String = ''):String
                {
                        var data:ByteArray = Base64.decodeToByteArray(txt);
                        var pad:IPad = new PKCS5;
                        var mode:ICipher = Crypto.getCipher(type, key, pad);
                        pad.setBlockSize(mode.getBlockSize());
                        mode.decrypt(data);
                        return Hex.toString(Hex.fromArray(data));
                }
        }
 
}

Here is the php class:

 
<?
class Crypt
{
        var $key = NULL;
        var $iv = NULL;
        var $iv_size = NULL;
 
        function Crypt()
        {
                $this->init();
        }
 
        function init($key = "")
        {
                $this->key = ($key != "") ? $key : "";
 
                $this->algorithm = MCRYPT_DES;
                $this->mode = MCRYPT_MODE_ECB;
 
                $this->iv_size = mcrypt_get_iv_size($this->algorithm, $this->mode);
                $this->iv = mcrypt_create_iv($this->iv_size, MCRYPT_RAND);
        }
 
        function encrypt($data)
        {
                $size = mcrypt_get_block_size($this->algorithm, $this->mode);
                $data = $this->pkcs5_pad($data, $size);
                return base64_encode(mcrypt_encrypt($this->algorithm, $this->key, $data, $this->mode, $this->iv));
        }
 
        function decrypt($data)
        {
                return $this->pkcs5_unpad(rtrim(mcrypt_decrypt($this->algorithm, $this->key, base64_decode($data), $this->mode, $this->iv)));
        }
 
        function pkcs5_pad($text, $blocksize)
        {
                $pad = $blocksize - (strlen($text) % $blocksize);
                return $text . str_repeat(chr($pad), $pad);
        }
 
        function pkcs5_unpad($text)
        {
                $pad = ord($text{strlen($text)-1});
                if ($pad > strlen($text)) return false;
                if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
                return substr($text, 0, -1 * $pad);
        }
}
 
?>

Now if you use the encrypt method of one you can send the data to the other one and decrypt it in the other language if you use the same key. Works like a charm. There is a mention that the key can only be 8 characters long but I haven’t tested it out.

, , , , , , , , ,

  1. #1 by Stefano - May 2nd, 2009 at 11:58

    Thank you for this post!

    DES provide a very little ecryption protection, try and use AES with 256bit key.
    It’s the only encryption algorythm that hasn’t been broken either theorically or by brute force yet.
    Ste

  2. #2 by Tim - June 20th, 2009 at 17:34

    I was wondering how to actually use the Crypt class in PHP. My main problem is with the key passed in through the init function. Do I pass in the exact same value as the key used in CryptoCode class, in this case “TESTTEST” or do I need to convert the PHP “TESTTEST” string into another format before passing it to the Crypt->init().

    I ask because I’m unable to decrypt data being passed from ActionScript. I get a 0 back from Crypt->encrypt().

  3. #3 by Tim - June 20th, 2009 at 20:36

    Never mind, I was able to find the problem. I was not initializing the PHP Crypt key properly because I was passing the key in through the constructor not the init() function.

  4. #4 by BubbleBoy - June 23rd, 2009 at 08:31

    Thanks! Interesting. It looks to me like you are NOT using AES in this script, although you say it in the intro? Did you implement AES as well?

    Very helpful anyway! Thanks!

  5. #5 by Atin - June 29th, 2009 at 03:08

    nice post man, but i am looking for an encryption and decryption in actionscript.. i tried hurlant, DES but its not working.. the encrypted code is not decrypted with its generated encrypted code.. i also tried xor encrypt decrypt but it fails to decrypt if the text has ‘and’ in it.. looking for help if anyone knows about this..

  6. #6 by MAADMAXX - July 3rd, 2009 at 00:11

    What a great post. I’m a intermediate/novice coder – would it be possible to provide working sample code in each direction? Would be greatly appreciated.

  7. #7 by Hong - October 14th, 2009 at 15:10

    I notice the decryption is not working sometimes. I went inside and found the root of the problem.

    For function pkcs5_unpad, this modification will ensure that decryption still goes through if there is no need for unpadding.

    if (strspn($text, chr($pad), strlen($text) – $pad) != $pad) return $text; //<– return $text instead of false when there is nothign to unpad

    It works for me but I am not a crypto artist so I am not exactly sure if this is the way to go.

    Comment and keep me with the game ppl. =)

  8. #8 by Hadi - November 7th, 2009 at 16:44

    if (strspn($text, chr($pad), strlen($text) – $pad) != $pad) return $text; //<– return $text instead of false when there is nothign to unpad
    blockquote>

    it seems that I have problem with Pading also… I submit the bug in as3Crypto their issues tab #28 but will you please explain a bit more about what you’re doing above? Thanks.

  9. #9 by AlexWD - November 12th, 2009 at 00:22

    I noticed some problems as well, but it’s not on the PHP end. Rather when decrypting on the PHP end I’m getting random chars appended to the front. I put a temporary solution that makes it work for me, but I’m not sure if it’s the right way to go because I don’t know the full extent of the problem. And it’s just a half-assed fix anyway.

  10. #10 by Shane - December 14th, 2009 at 03:32

    Would be really interested in a complete working AES version of this system with all the bugs removed. I was quite shocked to find out how much time I’ve had to spend finding a system to crypt data between php and actionscript. Yet still haven’t found a strong secure way.

(will not be published)
Subscribe to comments feed