I am trying to get and Erlang site to exchange information via `aes_cfb_128` encryption with a PHP site. I am writing a test implementation which will demonstrate that the PHP will decrypt what the Erlang encrypts and vice-versa - but I am having problems.

Here is the PHP source (apologies it is a bit shoddy - my PHP is no good - I am an Erlang programmer):

    <?php
    
    function dump($String, $Bin) {
    echo $String . " is " . ord($Bin[0]) . " " . ord($Bin[1]) . " " . ord($Bin[2]) . " " . ord($Bin[3]) . " " . ord($Bin[4]) . " " . ord($Bin[5]) . " " . ord($Bin[6]) . " " . ord($Bin[7]) . " " . ord($Bin[8]) . " " . ord($Bin[9]) . " " . ord($Bin[10]) . " " . ord($Bin[11]) . " " . ord($Bin[12]) . " " . ord($Bin[13]) . " " . ord($Bin[14]) . " " . ord($Bin[15]) . " " . ord($Bin[16]) . " " . ord($Bin[17]) . " " . ord($Bin[18]) . " " . ord($Bin[19]) . " " . ord($Bin[20]) . " " . ord($Bin[21]) . " " . ord($Bin[22]) . " " . ord($Bin[23]) . " " . ord($Bin[24]) . " " . ord($Bin[25]) . " " . ord($Bin[26]) . " " . ord($Bin[27]) . " " . ord($Bin[28]) . " " . ord($Bin[29]) . " " . ord($Bin[30]) . " " . ord($Bin[31]) ."\n";
    
    }
    
    $Key  = "abcdefghabcdefgh";
    $IV   = "12345678abcdefgh";
    $Text = "12345678123456781234567812345678";
    
    $KeySize = strlen($Key) * 8;
    $IVSize = strlen($IV) * 8;
    $TextSize = strlen($Text) * 8;
    
    $IVSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);
    echo "IVSze is " . $IVSize . " bytes or " . $IVSize * 8 . " bits\n";
    
    $BlockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);
    echo "BlockSize is " . $BlockSize . " bytes or " . $IVSize * 8 . " bits\n";
    
    $Crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $Key, $Text, MCRYPT_MODE_NOFB, $IV);
    
    $Decrypt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $Key, $Crypt, MCRYPT_MODE_NOFB, $IV);
    
    echo "Key   is   " . $Key  . " with size " . $KeySize  . "\n";
    echo "IV    is   " . $IV   . " with size " . $IVSize   . "\n";
    echo "Text  is   " . $Text . " with size " . $TextSize . "\n";
    echo "Crypt is " . $Crypt  . "\n";
    dump("Crypt", $Crypt);
    echo "Decrypt is " . $Decrypt . "\n";
    dump("Decrypt", $Decrypt);
    ?>

Here is the corresponding Erlang source:

    -module(test_crypto).
    
    -export([
             test/0
            ]).
    
    test() ->
        Key  = <<"abcdefghabcdefgh">>,
        IV   = <<"12345678abcdefgh">>,
        Text = <<"12345678123456781234567812345678">> ,
    
        KeySize  = bit_size(Key),
        IVSize   = bit_size(IV),
        TextSize = bit_size(Text),
    
        io:format("Key  is ~p with size ~p~n", [Key, KeySize]),
        io:format("IV   is ~p with size ~p~n", [IV, IVSize]),
        io:format("Text is ~p with size ~p~n", [Text, TextSize]),
    
        Crypt = crypto:aes_cfb_128_encrypt(Key, IV, Text),
        io:format("Crypt is ~p~n", [Crypt]),
        B64 = base64:encode(Crypt),
        io:format("Crypt B64 is ~p~n", [B64]),
    
        Decrypt = crypto:aes_cfb_128_decrypt(Key, IV, Crypt),
        io:format("Decrypt is ~p~n", [Decrypt]),
        ok.

Here is the PHP output:

    gordon@hypernumbers:~/crypto$ php test_crypto.php
    IVSze is 16 bytes or 128 bits
    BlockSize is 16 bytes or 128 bits
    Key   is   abcdefghabcdefgh with size 128
    IV    is   12345678abcdefgh with size 16
    Text  is   12345678123456781234567812345678 with size 256
    Crypt is ��^DЭZ�!�)�y�9�������ht���'!
    Crypt is 139 182 94 68 208 173 127 90 14 236 33 230 41 29 210 121 153 57 173 191 237 169 242 222 217 104 116 144 240 175 39 33
    Decrypt is 12345678123456781234567812345678
    Decrypt is 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56

Here is the Erlang output:

    7> test_crypto:test().
    Key  is <<"abcdefghabcdefgh">> with size 128
    IV   is <<"12345678abcdefgh">> with size 128
    Text is <<"12345678123456781234567812345678">> with size 256
    Crypt is <<139,182,94,68,208,173,127,90,14,236,33,230,41,29,210,121,147,172,
               114,74,61,11,162,5,112,104,102,63,24,78,34,179>>
    Crypt B64 is <<"i7ZeRNCtf1oO7CHmKR3SeZOscko9C6IFcGhmPxhOIrM=">>
    Decrypt is <<"12345678123456781234567812345678">>
    ok

As you can see both Code Blocks cycle themselves correctly - but they will not work together because they do not create identical cyphertext.

The first 16 bytes of the cypertext are the same - but the second block of 16 bytes is different.

I know this algorithm uses the first output block in the encryption of the second one - so I suspect there is some jiggery-pokery going on between how the Erlang ``crypto`` module is doing it and the PHP `mcrypt` code.

I tried getting help on StackOverflow http://stackoverflow.com/questions/14550195/crypto-between-erlang-and-php but it was mostly me talking to myself :(