ГПСЧ TreeShell и алгоритм шифрования обзор


Я всегда хотела придумать свой собственный алгоритм шифрования. Вчера вечером я начал писать алгоритм "TreeShell" шифрования, который использует сдвига и XOR операции на уровне битов для шифрования.

Этот алгоритм позволяет произвольной длины данных и ключ защиты. Ключ не хранится, но хэшируется вместе с случайных IV. Случайный IV, который формируется из собственного ГПСЧ TreeShell, который приведен ниже.

Длина окончательный шифротекст не зависит от длины ключа, при условии, но фиксированной длины, ИЖ добавляться в зашифрованном виде.

<?php

class TreeShell{

    const BLOCK_SIZE = 16;
    const BYTES = 4;
    const KEY_LENGTH = 256;

    public function encrypt($key, $plain){
        $iv = $this->iv();
        $ivs = $this->ivArrToString($iv);
        $keyHash = $this->keyHash($key, $ivs, $iv);

        $kHL = count($keyHash);
        $l = strlen($plain);
        $s = '';
        for($i = 0; $i < $l; $i+=4){
            $k = $i % ($kHL);
            $m = $this->stringToBlock($plain, $i);
            $j = $m ^ $keyHash[$k];
            $s .= $this->blockToString($j);
        }
        return $ivs . $s;
    }

    public function decrypt($cipher, $key){
        $ivsL = self::BLOCK_SIZE * self::BYTES;
        $ivs = substr($cipher, 0, $ivsL);
        $iv = $this->stringToIVArr($ivs);
        $keyHash = $this->keyHash($key, $ivs, $iv);

        $cipher = substr($cipher, $ivsL);
        $l = strlen($cipher);
        $kHL = count($keyHash);
        $s = '';
        for($i = 0; $i < $l; $i+=4){
            $k = $i % ($kHL);
            $m = $this->stringToBlock($cipher, $i);
            $j = $m ^ $keyHash[$k];
            $s .= $this->blockToString($j);
        }
        return rtrim($s);
    }

    private function iv(){
        $iv = array();
        for($i = 0; $i < self::BLOCK_SIZE; $i++){
            $iv[] = $this->prng(286331153, 4294967295);
        }
        return $iv;
    }

    private function stringToIVArr($ivs){
        $a = unpack('C*', $ivs);
        $l = count($a);
        $r = array();
        for($i = 1; $i <= $l; $i+=4){
            $c = 0;
            if(array_key_exists($i, $a)){
                $c += ($a[$i] << 24);
            }
            if(array_key_exists($i + 1, $a)){
                $c += ($a[$i + 1] << 16);
            }
            if(array_key_exists($i + 2, $a)){
                $c += ($a[$i + 2] << 8);
            }
            if(array_key_exists($i + 3, $a)){
                $c += ($a[$i + 3]);
            }
            $c = (($c & 0xFFFF) << 16) | (($c >> 16) & 0xFFFF);
            $r[] = $c;
        }
        return $r;
    }

    private function ivArrToString($iv){
        $s = '';
        foreach($iv as $a){
            $s .= $this->blockToString($a);
        }
        return $s;
    }

    private function blockToString($block){
        $block = (($block & 0xFFFF) << 16) | (($block >> 16) & 0xFFFF);
        $a = array(
            ($block >> 24) & 0xFF,
            ($block >> 16) & 0xFF,
            ($block >> 8) & 0xFF,
            ($block) & 0xFF
        );
        $s = '';
        foreach($a as $v){
            $s .= chr($v);
        }
        return $s;
    }

    private function stringToBlock($s, $i){
        $s = substr($s, $i, 4);
        $c = unpack('C*', $s);
        while(count($c) < 4){
            $c[] = 0;
        }
        $block = ($c[1] << 24) | ($c[2] << 16) | ($c[3] << 8) | ($c[4] << 0);
        $block = (($block & 0xFFFF) << 16) | (($block >> 16) & 0xFFFF);
        return $block;
    }

    private function keyHash($key, $ivs, $iv){
        $a = array();
        $l = strlen($key);
        $r = array();

        $y = $l;
        $o = $key;
        while($l < self::KEY_LENGTH){
            $key .= $o;
            $l += $y;
        }

        $key .= $ivs;
        $l += strlen($ivs);

        for($i = 0; $i < $l; $i+=4){
            $k = $i % self::BLOCK_SIZE;
            $m = $this->stringToBlock($key, $i);
            $j = $m ^ $iv[$k];
            $r[] = $this->hash32shift($j);
        }
        return $r;
    }

    private function bitRotate($value, $bits){
        if ($bits >0 ) {
            $bits %= 32;
            $value = ($value << $bits) | ($value >> (32 - $bits));
        } elseif ($bits < 0) {
            $bits = -$bits % 32;
            $value = ($value >> $bits) | ($value << (32 - $bits));
        }
        return $value;
    }

    private function hash32shift($key){
        $c2 = 0x27d4eb23; // a prime or an odd constant
        $key = ($key ^ 61) ^ $this->bitRotate($key, 16);
        $key = $key + ($key << 3);
        $key = $key ^ $this->bitRotate($key, 4);
        $key = $key * $c2;
        $key = $key ^ $this->bitRotate($key, 15);
        return $key;
    }


    private function prng($min = null, $max = null){
        static $seed = null;
        if($seed == null){
            if($min && $max){
                $seed = 2.14;
            }elseif($min){
                $seed = 1.24;
            }elseif($max){
                $seed = 0.78;
            }else{
                $seed = 0.65;
            }
            $i = ceil(time() % 50 * 5) + 10;
            while($i --> 0){
                $f = (sin(5 * pow($seed, 3)) + cos(10 * pow($seed, 2)) + 2) / 4;
                if($f > 0.5){
                    $seed += ceil($f * 96);
                }else{
                    $seed -= ceil($f * 32);    
                }
            }
        }
        $f = (sin(2 * pow($seed, 2)) + cos(3 * $seed) + sin(3 * $seed) + cos(2 * $seed) + 4) / 8;
        if($f > 0.5){
            $seed -= ceil($f * 1440);
        }else{
            $seed += ceil($f * 512);    
        }

        if(func_num_args() == 2){
            $f = ($f * ($max - $min)) + $min;
            if(is_int($min) && is_int($max)){
                $f = (int)ceil($f);
            }
        }

        return $f;
    }

}

Я проверил случайность ГПСЧ, а также целостность данных зашифрованного текста создается (путем шифрования после расшифровки образец сообщение, используя тот же ключ). Они выглядят хорошо для меня.

Как я могу определить, если этот алгоритм может быть взломан в течение разумного времени?

Примечание: В настоящее время проблема с этим алгоритмом состоит в том, что дан открытый текст шифруется с помощью ключа "азбука", а расшифровывается с помощью ключа "БХД", некоторые прямым текстом расшифрованы. Я работаю, чтобы исправить это. Если вы пишете алгоритм, что изменения в этот алгоритм, чтобы исправить эту проблему?
Хэш-функция была исправлена, чтобы сделать его более лавинного эффекта. Ранее лавинный эффект вряд ли был замечен, как подобная фраза может раскрыть частично зашифрованном виде.



308
3
задан 27 октября 2011 в 02:10 Источник Поделиться
Комментарии
2 ответа

Во-первых, важная оговорка: я не являюсь крипто экспертов (IANACE). Из-за этого, я не буду рассматривать ваш код в конкретных. Я также призываю вас доверять только отзывам экспертов, крипто.

Как я понимаю, самое главное, чтобы решить, если ваш алгоритм-это сильное, чтобы узнать о существующих методик для взлома алгоритмов, а затем применить эти приемы против собственного алгоритма. Ваш алгоритм должен быть в состоянии выдержать все существующие известные методы.

Большинство доморощенных шифры легко разбить, потому что они не учитывают методов, используемых опытные криптографы. Например, существует множество типов известных-открытым текстом атака,-шифротекст атак, и так далее. (Многие из них занесены в отличном Брюса Шнайера Прикладная криптография книга.) Вам нужно знать, как применять их все.

Другой класс нападения, чтобы рассмотреть на стороне-канал атаки, и, в частности, сроки оракул атак. Ваша функция длиться дольше или короче, если ключ является недействительным? Это дает злоумышленнику ценную информацию, а в худшем случае позволяет восстановить правильный ключ.

Я также не могу комментировать в силу вашей ГПСЧ, но подумайте, где ваши источники энтропии, и сможет ли злоумышленник может манипулировать людьми для достижения меньше, чем случайный выход.

Что касается вашего КДФ (ключевая функция деривации), то грамотно подобранные ключевые фразы в кодировке ASCII (наиболее распространенный случай) дают хорошее покрытие возможных ключей. Требуется хорошее освещение, так что рассылка ключей не перекошен для класса общих фраз---что бы дать злоумышленнику ценную информацию. Также рассмотреть вопрос о целесообразности подобных фраз порождают аналогичные ключи. Они не должны. Небольшие изменения в пароль должен повлечь за собой огромные изменения в ключ, так что фраза не так легко вывести из рабочего ключа.

Есть и другие вещи, чтобы рассмотреть, но опять же, я не эксперт в криптографии. Но я надеюсь, что это поможет вам начать. :-)

1
ответ дан 27 октября 2011 в 03:10 Источник Поделиться


Они выглядят хорошо для меня.

Уверен, вы человек. Но то, что “выглядит” случайным людям не всегда должна быть случайной. Ты проводил какие-нибудь тесты, как DieHarder люкс (при условии Роберт Браун из Университета Дьюка) для проверки на истинную случайность вы ГПСЧ реализации? Вы определенно должны проверить для энтропии и т. д. прежде чем даже думать, что твой ГПСЧ действительно как случайные, как кажется! Есть и более мелкие инструменты, такие как адррес fourmilab по ЛОР, но так как вы не ориентируетесь криптографии, я бы пойти на DieHarder люкс так как он охватывает больше тестов.

Также...

Ваш алгоритм использует псевдо-генератор случайных чисел - который имеет тенденцию быть криптографически опасности, потому что он не является истинно случайным. Вместо того, чтобы на выходе ГПСЧ ходит вдоль фиксированной последовательности ГПСЧ производит. В худшем случае, злоумышленник только нужно восстановить несколько битов ГПСЧ чтобы восстановить целое состояние ГПСЧ ... что бы так называемое "состояние восстановления атаки".


Кстати.: Предложи зайти в крипто.ЮВ и задать несколько вопросов, если вам нужно больше indeep информацию, относящуюся к криптографии, криптографии, и или потенциальных крипто, связанных с вопросами безопасности.

0
ответ дан 10 ноября 2013 в 12:11 Источник Поделиться