Проблемы с mcrypt, при сериализации сессий БД

shady

Guest
Проблемы с mcrypt, при сериализации сессий БД

//Фу гоню!!! Это не самокритика;) само как-то в юмор запостилось! в PHP+БД писал ведь
//ну вобщем, ниже вопрос... (модератор, если можно , перенесите пост пожалуйста... мда уж)


Приветствую!
Собственно, постораюсь подробно описать проблему... исходник прилогается;)
Есть скрипт, который реализует собственные обработчики записи/чтения и т.д. пользовательской сессии, в частности запись/чтение данных сессии в БД и шифрование (использую mcrypt).

Запись/Чтения из БД работает правильно (там собственно и ошибиться то как-бы негде;), однако, непонятное поведение в случае шифрования -

после 5-7 раза кодирования/декодирования данных сессии, перед декодированной строкой данных, оказывается какой-то мусор... причём, при проверки с отключённым кодированием, в базу пишется то что и должно писаться, когда же при чтении из БДи последующем декодировании проявляется эта бага (моя криворукость? ;)
такое впечатление, что при mdecrypt_generic не корректно инициализируется буфер...
например (см. исходник), при print_r($_SESSION) видим нечто вроди
Array ( [uГW9е╖�;Вр░s�11-55-05, 27-04-06";r] => 0 [c] => 11-56-48, 27-04-06 [r] => 11-56-48, 27-04-06 )

т.е. декодируется нормально, но что эта за [uГW9е╖�;Вр░s в самом начале???

Вобщем, народ, кто что может подсказать - буду весьма и весьма рад!
***
php 6.0.0 (тестил также просто на 5.0, 5.1)
Mysql 5.1
Apache 1.3.33
OS: Win/NIX

PHP:
class SessionEncrypt extends SessionPersistent {
    protected $td = null;
    protected $iv = null;
    protected $ks = null;
    protected $key = null;
//METHODS
    public function __construct(&$entity) {
        parent::__construct($entity);
        
        $this->td= mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CFB, '');
        $this->iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND);
        $this->ks = mcrypt_enc_get_key_size($this->td);
        $this->key = substr(sha1(session_id()), 0, $this->ks);
    }
    
    public function __destruct() {
        parent::__destruct();

        session_write_close();
        mcrypt_module_close($this->td);
    }    
    
    public function open($save_path, $session_name) {
        return $this->entity->open($save_path, $session_name);
    }
    
    public function close() {
        return $this->entity->close();
    }
    
    public function read($id) {
        $res = $this->entity->read($id);    //данные из обрамляющего враппера
        
        mcrypt_generic_init($this->td, $this->key, $this->iv);
        $res =  empty($res) ? $res : mdecrypt_generic($this->td, $res);
        mcrypt_generic_deinit($this->td);
        return $res;
    }
    
    public function write($id, &$session_data) {
        mcrypt_generic_init($this->td, $this->key, $this->iv);
        empty($session_data) ?
            $this->entity->write($id, $session_data) :
            $this->entity->write($id, mcrypt_generic($this->td, $session_data));
        mcrypt_generic_deinit($this->td);
        return true;
    }
    
    public function destroy($id) {
        return $this->entity->destroy($id);
    }
    
    public function gc($life_time) {
        return $this->entity->gc($life_time);
    }
}    //class SessionEncrypt
?>
Как устроено чтение/запись в вырезанном коде, думаю понятно, да и не важно это впринципе, так как все те части работают корректно...
 

Alexandre

PHPПенсионер
//Фу гоню!!! Это не самокритика;) само как-то в юмор запостилось!
+1 оставить в юморе
:)

shady ни кому не интерестно разбираться с километрами твоего кода. выдели и оставь ту часть которая отвечает только за шифрование/дешифрования.

после 5-7 раза кодирования/декодирования данных сессии, перед декодированной строкой данных, оказывается какой-то мусор...
Потом - это что за криптомания - прогонять шифрование 3-5 раз? От этого криптостойкость сообщения не изменится (если используется один и тотже ключ)

отладь сперва на одном прогоне.

:rolleyes:
 

shady

Guest
Автор оригинала: Alexandre
shady ни кому не интерестно разбираться с километрами твоего кода. выдели и оставь ту часть которая отвечает только за шифрование/дешифрования.
пожалуй да, народ тут не глупый, и так разберётся... оставил только комменты и сам класс с криптухой

Автор оригинала: Alexandre
Потом - это что за криптомания - прогонять шифрование 3-5 раз?
Нет, дело в том, что тот мусор вылазит только после 5 (примерно) раза передачи данных от скрипта к браузеру... т.е. 5 раз в базу пишется/читается без каких-либо заглючек... "мусор" криптования появляется только после 5-го раза сеанса сессии...


Кстати, как только что выяснилось, "мусор" появляется для всех алгоритмов криптования, кроме MCRYPT_GOST ...
 

SID

ReadOnlyТеаm
shady
а как ты определил что у тебя php шестой версии?
 

shady

Guest
Автор оригинала: SID
shady
а как ты определил что у тебя php шестой версии?
snaps.php.net

-~{}~ 27.04.06 16:29:

.... ааа модератор, они смеются с меня, перенесите тему плиз, гы
;)))
 

Alexandre

PHPПенсионер
"мусор" криптования появляется только после 5-го раза сеанса сессии...
Ну так бы и говорил... и еще маленький совет, чтоб твой текст был более понятен и читабелен - нужно его заключить в псевдотеги [ php ] (без пробелов), попробуй (а то у меня нет прав менять твой ответ)

-~{}~ 27.04.06 17:17:

начни с алгоритмов блочного шифрования, типа RC-2 или DEC, мусор может появляться в связи с использованием вектора инициализации, отладь сперва без его использования. ну пример могу привести из мана:
PHP:
    $key = "This is a very secret key";
    $text = "Meet me at 11 o'clock behind the monument.";
    echo strlen($text) . "\n";

    $crypttext = mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_ECB );
    echo strlen($crypttext) . "\n";
-~{}~ 27.04.06 17:23:

и еще - самое наверно главное, надо отойти от использования таких конструкций $key = "This is a very secret key"; и использовать строго определенную длинну $key в соответсвии с выбранным алгоритмом
RC2 до 1024 бит
DES 56
CAST-256 256
CAST-128 128
 

shady

Guest
Автор оригинала: Alexandre
и еще - самое наверно главное, надо отойти от использования таких конструкций $key = "This is a very secret key"; и использовать строго определенную длинну $key в соответсвии с выбранным алгоритмом
Видимо из-за первоначального форматирования без использования метатэгов, плохо различима строка
PHP:
       $this->key = substr(sha1(session_id()), 0, $this->ks);
теперь исправил...


А собственно, как отладить-то? Всмысле, добиться с \0 (вектор дефолтом заполняется \0)???

Те же граблиз... хм...
т.е. при использовании замапленого 0-ми вектора - ок, при его инициализации - появляется мусор...

В чём в PHP заключается отладка этого вектора?
 

Alexandre

PHPПенсионер
В чём в PHP заключается отладка этого вектора
в чем заключается отладка вектора - я не отвечу, (скорее всего отладка должна быть без него)

просто назначение вектора инициализации: добавление дополнительного мусора в твое кодированное сообщение, чтоб его было труднее разкодировать. Соответственно, этот мусор как-то накапливается и начинает проявляться....
а может у тебя где-то в коде глюк.
$this->key = substr(sha1(session_id()), 0, $this->ks);
я так понимаю, сессион ай-ди хешируем, обрезаем и получаем ключ? Есть такое праило, что ключи не должны вычисляться, хотя для твоих задач и так потянет.

-~{}~ 27.04.06 20:09:

хм, я наверно заню в чем дело, ;)
ты как и что пишешь в сессию (кусок кода плииз).
скорее всего тебе нужно зашифрованный текст кодировать base64 а потом его уже записывать в сессию.
просто кодированный поток - это набор произвольных бит, в нем могут попадатьмя произвольные управляющие символы, такие как конец строки или конец файла... :)
и это может произойти на любом шаге итерации, естественно
когда это обратно читается - то происходит сбой данных.
По этому попробуй, перез записью в сессию - кодировать данные base64, соответственно при чтение обратный процесс.
 

shady

Guest
Автор оригинала: Alexandre
а может у тебя где-то в коде глюк.я так понимаю, сессион ай-ди хешируем, обрезаем и получаем ключ? Есть такое праило, что ключи не должны вычисляться, хотя для твоих задач и так потянет.
Для задач "демки" конечно потянет;)
Кстати, а какой подход для работы с сессией можите предложить для параноиков? ;)

Автор оригинала: Alexandre
хм, я наверно заню в чем дело, ;)
ты как и что пишешь в сессию (кусок кода плииз).
В сессию пишу "классическим" способом;) т.е. через $_SESSION...
ну например
PHP:
$_SESSION['someData'] = array('one'=>1, 'two'=>2);
Автор оригинала: Alexandre
скорее всего тебе нужно зашифрованный текст кодировать base64 а потом его уже записывать в сессию.
просто кодированный поток - это набор произвольных бит, в нем могут попадатьмя произвольные управляющие символы, такие как конец строки или конец файла...
Да, конечно, для порстоты не буду приводить куски кода, но скажу, что кодированные данные сессии пишутся в атрибут таблицы
типа BLOB, с предварительным экранированием - addslashes.

За запись и чтение данных я "отвечаю" так как кроме криптования, есть много других врапперов, например как запись в Зипе, запись криптухи по RSA (здесь всё работает)...
"Мусор" проявляется только в случае использования mcrypt...
 

Фанат

oncle terrible
Команда форума
А можно попросить смоделировать действия злоумышленника, который сможет прочесть данные сессии, если они будут храниться без шифрования?
 

shady

Guest
Я вот тут поЭксперементировал немного, такой интересный факт проявился... всё нормально если кодирование и декодирование осуществлять в одном методе... когде же вектор, рессурс и т.д. (т.е. что то типа
PHP:
    protected $td = null;
    protected $iv = null;
    protected $ks = null;
    protected $key = null;
) объявлены как свойства класса, появляется этот мусор...
Блин, но это же не решение проблемы то... должно ведь и так работать???

проверял - все эти свойства сохраняют свои значения между вызовами read\write событий сессии, однако, "мусор" упорно не желает исчезать...

-~{}~ 28.04.06 10:53:

Автор оригинала: Фанат
А можно попросить смоделировать действия злоумышленника, который сможет прочесть данные сессии, если они будут храниться без шифрования?
Можно... действия примерно таковы:
Злоумышленник, завладев данными сессии, идёт на phpclub и в юморе постит:
"ЙО! братва! там ламерюги магазин написали - сессии "as is" валяюццо"

Это конечно самый удачный сценарий развития событий...
Я не говорю про хранение CVV2 и т.д. , даже "рассекречивание" адреса пользователя/клиента может повлечь за собой весьма негативные последствия... и естественно, удар по репутации CMS и студии ;)
 

Фанат

oncle terrible
Команда форума
стоп.
я тебя не спрашивал, что злоумышленник будет делать с данными, которые он получит.
я тебя спросил, как именно он получит.
 

shady

Guest
Автор оригинала: Фанат
стоп.
я тебя не спрашивал, что злоумышленник будет делать с данными, которые он получит.
я тебя спросил, как именно он получит.
Ну дык, никто никогда не видел взломанных хостеров/криворуких PHP-программеров;) ?

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

-~{}~ 28.04.06 11:09:

Автор оригинала: Фанат
А можно попросить смоделировать действия злоумышленника, который сможет прочесть данные сессии, если они будут храниться без шифрования?
сорри, может я не верно просто понял вопрос, но ИМХО, ты спрашивал, что он будет делать, если всё-таки их получит...
ну хотя не суть важно.
 

Фанат

oncle terrible
Команда форума
не понял
а как именно будет защищена конфиденциальность информации, если будет взломан хостер или криворукий (кхе-кхе - как самокритично) программер?
 

shady

Guest
Автор оригинала: Фанат
не понял
а как именно будет защищена конфиденциальность информации
отсутствием возможности в срок валидности текущией сессии, выполнить действия от лица клиента (ессно, разные там IP в качестве sole при использговании криптух само сабой, но например, опытному "злоумышленнику"не составит труда перебить IP-пакет, где будет стоять ИП жертвы... а нафик ответ-то нужен? требуемое действие мы и так осуществили - прикинулись аутентифицированным клиентом)

Автор оригинала: Фанат
если будет взломан хостер или криворукий (кхе-кхе - как самокритично) программер?
Ну, пока я упорно продолжаю постить - я ворошающий программер, криворукий, это если даже не удосужится сделать хотя бы такое...

Фанат, по логике вашего поста, я пологаю, что Вы пытаетесь помочь мне понять - Действительно ли мне это нужно...
Давайте априори положим, что это мне нужно... действительно нужно ;)
 

Фанат

oncle terrible
Команда форума
отсутствием возможности в срок валидности текущией сессии, выполнить действия от лица клиента
откуда я всё в толк не возьму - откуда возьмётся это отсутствие?

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

Alexandre

PHPПенсионер
я тебя спросил, как именно он получит.
Фанат, хоть и остр на язык, но он наводит на довольно умные рассуждения, которые надо уметь читать между строк, а не быть обиженной девочкой.

Попробую растолковать его мысли:

если злоумышлонник сможет получить данные сессии, то он с такойже простотой сможет иметь доступ к источникам пхп (если они не будут закодированы), а отсюда - доступ ко всей информации, которая может быть доступна скрипту. А по сему, криптостойкость системы не выше надежности разрабатываемой системы и надежности хостера.

Для криптостойких систем используются именно удаленные сервера ключей, а не вычистяются ключи путем хеширования иди сессии.
В сессию пишу "классическим" способом т.е. через $_SESSION
А вот меня интересовал, кусок кода, которым ты кодируешь сессию, т.е. записываешь в сессию кодированные данные - или я не правильно тебя понял -
ты их в сессию не записываешь, а хранишь в зашифрованном виде в поле BLOB.

я бы мог помочь советом, если бы понял ход работы программы(опиши по пунктам) , особенно тот кусок - где используется сессия и где происходит шифрование, куда потом идет эта информация, как потом она извлекается.
 

shady

Guest
Автор оригинала: Фанат
откуда я всё в толк не возьму - откуда возьмётся это отсутствие?
В данных сессии, например, может храниться непосредственно сам товар, адрес доставки товара и т.д.
Если данные сессии, если данные сессии хранятся не в зашифрованном виде - в случае взлома хостера, злоумышленнику ничего не помешает просто тупо подменить эти данные на свои; с какой целью он это сделает, и что там будет за инфа - дело третье...

Автор оригинала: Фанат
я помогаю тебе понять, что то, чем ты занимаешься - идиотизм.
Ну зачем же так сразу идиотизм, например вы пологаетесь только на права доступа к фалам/аутентификацию БД?
 

Alexandre

PHPПенсионер
запись криптухи по RSA
Почему выбран именно RSA ?
ответ что с ним все работает - не ответ.
RSA - представляет алгоритм с несимметричным шифрованием, т.е. с двумя ключами?
Если первый ключ вычисляется из Иди сессии? Где и как у тебя формируется второй ключ?
Для RSA ключи формируются единожды парой (секретный и публичный) и потом используются оба ключа.
 
Сверху