Search code examples
phpactionscript-3aesecbas3crypto

How to decrypt with as3crypto string encrypted with by aes-256-ecb?


String is encrypted with php as here. It can be decrypted by this with parameters: Rijndael-256, ECB and Base64. But it cannot be decrypted by my ActionScript code:

var text:String = "Some data";
var key:ByteArray = new ByteArray();
key.writeUTFBytes("SomePassword");
key.position = key.length;
for (var i:int = key.length; i < 256 / 8; i++) {
    key.writeByte(0);
}
var pad:IPad = new NullPad();
var cipher:ICipher = Crypto.getCipher("aes-256-ecb", key, pad);
var data:ByteArray = Base64.decodeToByteArray(text);
cipher.decrypt(data);
trace(data.toString());

UPD:

"It cannot be decrypted" means I get wrong plain text.

In php plain text is encrypted by aes-256-ecb firstly. Then it is encoded by Base64. In ActionScript these stepsarw being done in reverse order.

UPD2:

Test for encoding-decoding:

var key:ByteArray = new ByteArray();
key.writeUTFBytes("Some password");
key.position = key.length;
for (var i:int = key.length; i < 256 / 8; i++) {
    key.writeByte(0);
}
trace(key.toString());
var data:ByteArray = new ByteArray();//plain text
data.writeUTFBytes("Hello, my dear World! Hello, the Sun! Hello, the Moon! Hello! Hello! Hello!");
var pad:IPad = new NullPad();
var cipher:ICipher = Crypto.getCipher("aes-256-ecb", key, pad);
trace(data.toString());//trace plain text
cipher.encrypt(data);
trace(data.toString());//trace encrypted text
cipher.decrypt(data);
trace(data.toString());//trace decrypted text

The output after halting at cihper.encrypt(data) is:

Some password
Hello, my dear World! Hello, the Sun! Hello, the Moon! Hello! Hello! Hello!
[Fault] exception, information=Error: Error #2030: End of file found.

UPD3:

It works right with PKCS5 padding:

var pad:IPad = new PKCS5();
var cipher:ICipher = Crypto.getCipher("aes-256-ecb", key, pad);
pad.setBlockSize(cipher.getBlockSize());

Output is:

Some password
Hello, my dear World! Hello, the Sun! Hello, the Moon! Hello! Hello! Hello!
$ú^{±àÙ[pm|x¿9¡ÃZsI D¾`©4¾þÂõ,J
('èfÑk1ôì&­ªQƆfbÇåòþ§VµÄs   ¦p<iÿ
Hello, my dear World! Hello, the Sun! Hello, the Moon! Hello! Hello! Hello!

UPD4:

For data gotten from php (as here) code with PKCS5 padding running halts here. And with Null padding it doesn't halts but decrypted data is wrong.


Solution

  • Quoting the code in your last post:

    return trim(
        base64_encode(
            mcrypt_encrypt(
                MCRYPT_RIJNDAEL_256,
                $sSecretKey, $sValue, 
                MCRYPT_MODE_ECB, 
                mcrypt_create_iv(
                    mcrypt_get_iv_size(
                        MCRYPT_RIJNDAEL_256, 
                        MCRYPT_MODE_ECB
                    ), 
                    MCRYPT_RAND)
                )
            )
        );
    

    MCRYPT_RIJNDAEL_256 isn't AES. MCRYPT_RIJNDAEL_128 is. Rijndael has variable block sizes. AES is a subset of Rijndael with fixed block sizes.

    The number after MCRYPT_RIJNDAEL_* is referring to the block size. So MCRYPT_RIJNDAEL_256 is Rijndael with a 256-bit block size. MCRYPT_RIJNDAEL_128 is Rijndael with a 128-block size, aka AES.

    Also, if you're going to use MCRYPT_MODE_ECB I'd replace the mcrypt_create_iv() call with an empty string of a bunch of null bytes. ECB as a block mode does not use an IV.

    Finally, my own personal recommendation, since this is all very counter intuitive with mcrypt, is to use phpseclib, a pure PHP AES implementation.