Ошибки дешифрования данных as3crypto blowfish в PHP - PullRequest
0 голосов
/ 08 августа 2011

В данный момент я новичок в ActionScript 3 и пытаюсь использовать библиотеку as3crypto для шифрования некоторых данных с помощью алгоритма blowfish перед отправкой их на сервер для обработки. Я знаю, что вы можете использовать https, но большинство браузеров по-прежнему отображают исходящие данные, что позволяет пользователю легко подделать запрос. Вот почему я хочу, чтобы пользователь видел запрос страницы, но не смог прочитать данные без расшифровки.

К сожалению для меня, документация по библиотеке as3crypto практически не существует, кроме комментариев в коде (которые не очень помогают). Я настроил флэш-сторону вещей с парой статических функций, чтобы «реализовать» шифрование as3crypto blowfish, и они прекрасно работают для шифрования / дешифрования только во флэш-памяти. Проблема возникает, когда я пытаюсь использовать ключ для расшифровки в PHP с использованием библиотеки mcrypt. Вывод, который я получаю, не является исходным кодом, и я потратил пару дней, пытаясь понять, почему безрезультатно.

Ниже приведен код и пояснения. Для целей этого примера использовался ключ «mykey» (без кавычек), а закодированные данные - «Hello World» (снова без кавычек).

Flash-код (as3crypto blowfish helper):

    package lib.ef.crypto
{
    import com.hurlant.util.Base64;
    import com.hurlant.crypto.Crypto;
    import flash.utils.ByteArray;
    import com.hurlant.crypto.symmetric.IPad;
    import com.hurlant.crypto.symmetric.ICipher;
    import com.hurlant.crypto.symmetric.NullPad;

    public class Blowfish
    {
        /**
        * Encrypts a string.
        * @param text  The text string to encrypt.
        * @param key  A cipher key to encrypt the text with.
        */
        static public function encrypt($text:String, $key:String=""):String
        {
            var cryptKey:ByteArray = new ByteArray();
            cryptKey.writeUTF( $key );

            var iPad:IPad = new NullPad();

            var crypt:ICipher = Crypto.getCipher('blowfish-cfb',cryptKey,iPad);

            iPad.setBlockSize( crypt.getBlockSize() );

            var cryptText:ByteArray = new ByteArray();
            cryptText.writeUTF( $text );

            crypt.encrypt( cryptText );

            trace( Base64.encodeByteArray( cryptText ) );

            return null;
        }

        static public function decrypt($text:String, $key:String=""):String
        {
            return new String();
        }

    }
}

Вывод этого варьируется от прогона к прогону, но для целей этого примера прогона я получаю закодированный в base64 вывод: EkKo9htSJUnzBmxc0A == '

Когда я передаю этот код в PHP, он декодируется с помощью base64, а затем передается в метод, описанный ниже, для его расшифровки:

public static function decrypt($crypttext,$key)
{

        if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
    $plaintext = '';
    $td        = mcrypt_module_open('blowfish', '', 'cfb', '');
    $blocksize    = mcrypt_enc_get_block_size($td);
    $iv        = substr($crypttext, 0, $blocksize);
    $crypttext = substr($crypttext, $blocksize);
    if (true)
    {
        mcrypt_generic_init($td, $key, $iv);
        $plaintext = mdecrypt_generic($td, $crypttext);
    }
    return $plaintext;
}

В этот момент вывод полностью не читается. Я подозреваю, что проблема может быть связана с тем, что либо реализация blowfish as3crypto неверна (маловероятно), либо это может быть связано с тем, какое заполнение он использует (в настоящее время - нулевое заполнение), или, наконец, я думал, что это может иметь что-то делать со случайно сгенерированным вектором инициализации в as3crypto, который не добавляется перед началом закодированной строки? Последний, который я не смог протестировать, потому что библиотека as3crypto большая, сложная и совсем не документирована. Я погуглил эту проблему и проверил все в течение пары дней, и я просто продолжаю придумывать непригодные данные в PHP. Я знаю, что если я смогу заставить работать систему Flash to PHP, я могу перепроектировать ее и запустить шифрование PHP to Flash.

Я приветствую любые отзывы по этому вопросу, так как на самом деле это стоило мне спать по ночам, лол. Заранее спасибо:)


Сегодня я провел дополнительное тестирование и попытался выяснить, был ли это вектор инициализации, как я и подозревал. Я не верю, что это проблема. Я изменил некоторые вещи во флэш-памяти, чтобы получить выход IV, использованный для генерации закодированного вывода:

 package lib.ef.crypto
{
    import com.hurlant.util.Base64;
    import com.hurlant.crypto.Crypto;
    import flash.utils.ByteArray;
    import com.hurlant.crypto.symmetric.IPad;
    import com.hurlant.crypto.symmetric.ICipher;
    import com.hurlant.crypto.symmetric.NullPad;

    public class Blowfish
    {
        /**
        * Encrypts a string.
        * @param text  The text string to encrypt.
        * @param key  A cipher key to encrypt the text with.
        */
        static public function encrypt($text:String, $key:String=""):String
        {
            var cryptKey:ByteArray = new ByteArray();
            cryptKey.writeUTF( $key );

            var iPad:IPad = new NullPad();

            var crypt = Crypto.getCipher('blowfish-cfb',cryptKey,iPad);

            iPad.setBlockSize( crypt.getBlockSize() );

            var cryptText:ByteArray = new ByteArray();
            cryptText.writeUTF( $text );

            crypt.encrypt( cryptText );

            cryptText.position = 0;

            var iv:ByteArray = crypt.IV;

            iv.position = 0;

            trace( Base64.encodeByteArray( iv ) );

            trace( Base64.encodeByteArray( cryptText ) );

            return null;
        }

        static public function decrypt($text:String, $key:String=""):String
        {
            return new String();
        }

    }
}

В этом примере я получил закодированный IV '1bcGpqIbWRc =' и закодировал зашифрованные данные 'XpgART3hNQO10vcgLA ==' Я подключил их к модифицированной функции PHP после того, как base64_decode () их:

<code> public static function decrypt($crypttext,$key,$iv=NULL)
    {

        if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
        $plaintext = '';
        $td        = mcrypt_module_open('blowfish', '', 'cfb', '');
        if( $iv === NULL ){
            $ivsize    = mcrypt_enc_get_iv_size($td);
            echo '<pre>'.$ivsize.'
'; $ iv = substr ($ crypttext, 0, $ ivsize); echo '
'.strlen($iv).'
'; $ crypttext = substr ($ crypttext, $ ivsize); } если ($ iv) { mcrypt_generic_init ($ td, $ key, $ iv); $ plaintext = mdecrypt_generic ($ td, $ crypttext); } вернуть $ открытый текст; }

Даже этот вывод неверен.Я провел несколько тестов, чтобы убедиться, что IV - это правильный размер как во flash, так и в PHP, но по какой-то причине сторона PHP просто не может расшифровать закодированный вывод blowfish из Flash.Я попытался использовать заполнение NULL и PKCS5 в as3crypto, и ни один из них не работает с системой PHP.Я проверил, чтобы убедиться, что строки IV одинаковы как во Flash, так и в PHP.Они оба используют одни и те же ключи.Оба используют режим CFB.Я не понимаюТот же алгоритм, тот же ключ, тот же IV, тот же режим, но они не могут расшифровать друг друга.Мне кажется, что реализация blowfish as3crypto может быть неправильной.Кто-нибудь может это подтвердить?

Ответы [ 2 ]

1 голос
/ 10 марта 2013

Thanx!Смотрите здесь правильный "расшифровать":

static public function decrypt(txt:String, k:String=""):String{

    var kdata:ByteArray;
    kdata = Hex.toArray(Hex.fromString(k));

    var data:ByteArray;
    data = Base64.decodeToByteArray(txt);

    var pad:IPad = new NullPad;
    var mode:ICipher = Crypto.getCipher('simple-blowfish-cbc', kdata, pad);
    pad.setBlockSize(mode.getBlockSize());
    mode.decrypt(data);
    data.position = 0;

    return data.readUTFBytes( data.bytesAvailable );

}
1 голос
/ 10 августа 2011

Проведя некоторое копание в файлах библиотеки as3Crypto и демонстрационном коде, я обнаружил, что проблема в том, что мне нужно использовать функцию getCipher с режимом simple-blowfish-cfb вместо режима blowfish-cfb. Зашифрованный вывод при вызове crypt.encyrpt (cryptText) будет затем уже с префиксом IV алгоритма, поэтому вы сделаете один вызов Base64.encodeByteArray (cryptText), чтобы получить выходные данные для отправки в PHP. Когда вы инициализируете PHP, как я описал выше, он отрежет IV от строки и расшифрует его должным образом. Надеюсь, это поможет всем, кто столкнется с этой проблемой.

«Правильный» код флэш-памяти и PHP * приведен ниже для всех вас, TLDR, для тех, кому просто нужно быстрое решение для копирования / вставки: P

* Примечание. Мне пришлось удалить некоторые специфичные для моего приложения вызовы в обоих примерах кода и не проверять их, чтобы убедиться, что они функционируют на 100%, но они должны достаточно проиллюстрировать концепцию / структуру, чтобы, если они не работают правильно "из коробки" вы можете легко исправить их для использования.

PHP "вспомогательный" класс:

class Blowfish
{

    public static function encrypt($plaintext,$key)
    {
        if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
        $td = mcrypt_module_open('blowfish', '', 'cbc', '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $key, $iv);
        $crypttext = mcrypt_generic($td, $plaintext);
        mcrypt_generic_deinit($td);
        $out = $iv.$crypttext;
        return $out;
    }

    public static function decrypt($crypttext,$key)
    {
        if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
        $plaintext = '';
        $td        = mcrypt_module_open('blowfish', '', 'cbc', '');
        $ivsize    = mcrypt_enc_get_iv_size($td);
        $iv        = substr($crypttext, 0, $ivsize);
        $crypttext = substr($crypttext, $ivsize);
        if ($iv)
        {
            mcrypt_generic_init($td, $key, $iv);
            $plaintext = mdecrypt_generic($td, $crypttext);
        }
        return $plaintext;
    }

}

Флэш-класс "помощник":

package [your package name]
{
    import com.hurlant.util.Base64;
    import com.hurlant.util.Hex;
    import com.hurlant.crypto.Crypto;
    import flash.utils.ByteArray;
    import com.hurlant.crypto.symmetric.IPad;
    import com.hurlant.crypto.symmetric.ICipher;
    import com.hurlant.crypto.symmetric.IVMode;
    import com.hurlant.crypto.symmetric.NullPad;

    public class Blowfish
    {
        /**
        * Encrypts a string.
        * @param txt  The text string to encrypt.
        * @param k  A cipher key to encrypt the text with.
        */

        static public function encrypt(txt:String, k:String=""):String
        {
            var kdata:ByteArray;
            kdata = Hex.toArray(Hex.fromString(k));

            var data:ByteArray;
            data = Hex.toArray(Hex.fromString(txt));

            var pad:IPad = new NullPad;
            var mode:ICipher = Crypto.getCipher('simple-blowfish-cbc', kdata, pad);
            pad.setBlockSize(mode.getBlockSize());
            mode.encrypt(data);

            return Base64.encodeByteArray( data );
        }

        /**
        * Decrypts a string.
        * @param txt  The text string to decrypt.
        * @param k  A cipher key to decrypt the text with.
        */

        static public function decrypt(txt:String, k:String=""):String
        {
            var kdata:ByteArray;
            kdata = Hex.toArray(Hex.fromString( Base64.decode( k ) ));

            var data:ByteArray;
            data = Hex.toArray(Hex.fromString(txt));

            var pad:IPad = new NullPad;
            var mode:ICipher = Crypto.getCipher('simple-blowfish-cbc', kdata, pad);
            pad.setBlockSize(mode.getBlockSize());
            mode.decrypt(data);
            data.position = 0;
            return data.readUTFBytes( data.bytesAvailable );
        }

    }
}
...