1

I've a django app which serves encrypted media files to Flash apps. Encryption in python is done with PyCrypto as follows (I include description too in case useful):

 def encrypt_aes(key, text):
    try:
        raw = _pad(text)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw))
    except Exception as e:
        print e.message
        return text


def decrypt_aes(key, text):
    try:
        enc = base64.b64decode(text)
        iv = enc[:AES.block_size]
        cipher = AES.new(key, AES.MODE_CBC, iv)
        return _unpad(cipher.decrypt(enc[AES.block_size:]))
    except Exception as e:
        print e.message
        return text

    def _pad(s):
    bs = 16
    return s + (bs - len(s) % bs) * chr(bs - len(s) % bs)

    def _unpad(s):
        return s[:-ord(s[len(s) - 1:])]

I cannot yet decrypt the Python provided media files (downloaded with LoaderMax by GreenSock, using 'DataLoader'). My AS3 code (using AS3Crypto) is as follows:

public static function decipher(_key:String):void{
    key=_key;
    cipher = Crypto.getCipher("simple-aes-cbc", Hex.toArray(key));
    cipher.decrypt(ByteArray(_content));    
}

I get

RangeError: Error #2006

One suspicion is that in Python I have 64bit base but I think that AS3 ByteArray is 32bit base. I have tried the below, but get the same Error.

cipher.decrypt(ByteArray(com.hurlant.util.Base64.decodeToByteArray(_content)));  

Another suspicion is that I have not appropriately removed 'padding' from the _content / set up my IV appropriately (which is specified by the padding I must remove from the _content). This should be done via that "simple" statement however. I have been trying this, but with no success:

var pad:IPad = new PKCS5
cipher = Crypto.getCipher("simple-aes", Hex.toArray(key),pad);
pad.setBlockSize(cipher.getBlockSize());

Could anyone advise on how I can fix this ? :)

Many thanks!

andyw
  • 3,505
  • 2
  • 30
  • 44
  • Are you sure you should not just treat the ciphertext to be binary already? You seem to be confused on the encoding method used, but who says encoding is used at all? – Maarten Bodewes May 04 '14 at 17:28
  • Encoding is being used (I've some good chaps doing the django end and they've tested it a lot). I most certainly am confused with the encoding/decoding, indeed encryption in general! By cipherText, you mean the content to be decrypted? Could you advise on how i could treat it as binary already (just remove ByteArray typecasting?). – andyw May 04 '14 at 17:35
  • What does the ciphertext (that's the encrypted plaintext alright) look like when it is being transferred? Is it a printable string? – Maarten Bodewes May 04 '14 at 17:46
  • Text and lots of strange characters – andyw May 04 '14 at 17:47
  • It is imagery/sounds/video that is being transmitted and needs decrypting. – andyw May 04 '14 at 17:48
  • OK, so decoding won't help, it's already binary. Is `_content` not already a `ByteArray`? Can you remove `ByteArray()` from the code? If not, what type *is* `_content`? – Maarten Bodewes May 04 '14 at 17:53
  • _content is ByteArray in theory. I have typecaste it as ByteArray as LoaderMax has it as * (it needs to be * as the DataLoader class extends a more generic class...) – andyw May 04 '14 at 17:55
  • When we stop all encrpytion and switch off decryption, jpgs get shown, sounds get played as expected (we typecaste as bytearray there too) – andyw May 04 '14 at 17:57

1 Answers1

0

OK finally figured out what was going wrong. Besides some AS3 tweaks, we wrongly were transmitting files as MP3/image (should have been text/html).

Our Python remains as above. Our AS3 is tweaked to the below.

Here's the AS3 class we used:

package com.xperiment.preloader
{

import com.greensock.loading.DataLoader;
import com.hurlant.crypto.Crypto;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.util.Base64;
import flash.events.Event;
import flash.utils.ByteArray;


public class EncryptedDataLoader extends DataLoader
{
    private static var backlog:Vector.<EncryptedDataLoader>;
    private static var cipher:ICipher;
    private var decrypted:Boolean = true;

    public function EncryptedDataLoader(urlOrRequest:*, vars:Object=null)
    {
        this.addEventListener(Event.COMPLETE,decryptL);
        super(urlOrRequest, vars);
    }

    public function decryptL(e:Event):void {
        trace("start decrypt");
        e.stopImmediatePropagation();
        this.removeEventListener(Event.COMPLETE,decryptL);

        backlog ||= new Vector.<EncryptedDataLoader>;
        backlog.push(this);
        if(cipher)  pingBacklog();
    }

    public function decipher():void
    {
        _content = Base64.decodeToByteArray( _content );
        cipher.decrypt( _content );     

        decrypted=true;
        this.dispatchEvent(new Event(Event.COMPLETE));
    }

    public static function setCipher(_key:String):void{
        var keyBA:ByteArray = new ByteArray;
        keyBA.writeMultiByte(_key, "iso-8859-1"); 
        cipher = Crypto.getCipher("simple-aes", keyBA);
        pingBacklog();
    }

    public static function kill():void{
        cipher.dispose();
        cipher = null;  
    }

    public static function pingBacklog():void{
        if(backlog){
            var encrypted:EncryptedDataLoader;
            while(backlog.length>0){
                encrypted=backlog.shift();
                encrypted.decipher();
            }
            backlog=null;
        }
    }
}

}

andyw
  • 3,505
  • 2
  • 30
  • 44