Просто еще один велосипед шифрования

от автора

Привет Хабр!
У меня время от времени возникает необходимость зашифровать какие-то данные в своих проектах, но неохота использовать готовые решения.
Поэтому я изобрел свой велосипед. Это почти простой XOR.

Проблема ХОР-шифрования.

Как говорит википедия,

Длина гаммы должна быть не меньше длины защищаемого сообщения (открытого текста). В противном случае для получения открытого текста потребуется подобрать длину гаммы, проанализировать блоки шифротекста угаданной длины, подобрать биты гаммы.

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

У меня — что-то вроде генератора псевдослучайных чисел.
И так, процедура шифрования:

1. Оригинальная строка конвертируется в HEX, затем разбивается на части по 2 символа

$encoded = bin2hex($str); $encoded = str_split($encoded, 2); 

2. Пароль хэшируется пока не набирает нужную длину, а потом тоже разбивается на части по 2 символа

$binkey = md5($key); for($i=0;$i<(count($encoded)/16)+1;$i++){ 	$binkey .= md5($key.$binkey); } $binkey = str_split($binkey, 2); 

3. Ксорим

for ($i=0;$i<count($encoded);$i++){ 	$a = $encoded[$i]; 	$returnment .= bin2hex( 		pack('H*', $a) 		^ 		pack('H*', $binkey[$i]) 	); } 

4. Конвертируем назад в бинарные данные, потом в base64. Заменяем спецсимволы base64

$returnment = hex2bin($returnment); $returnment = base64_encode($returnment); $returnment = str_replace('+', '-', $returnment); $returnment = str_replace('/', '_', $returnment); 

Вот что у нас получилось:

$encoded = bin2hex($str); $encoded = str_split($encoded, 2); $binkey = md5($key); for($i=0;$i<(count($encoded)/16)+1;$i++){ 	$binkey .= md5($key.$binkey); } $binkey = str_split($binkey, 2); $returnment = ''; for ($i=0;$i<count($encoded);$i++){ 	$a = $encoded[$i]; 	$returnment .= bin2hex( 		pack('H*', $a) 		^ 		pack('H*', $binkey[$i]) 	); } $returnment = hex2bin($returnment); $returnment = base64_encode($returnment); $returnment = str_replace('+', '-', $returnment); $returnment = str_replace('/', '_', $returnment); return $returnment; 

Расшифровываем так же.

$str = str_replace('-', '+', $str); $str = str_replace('_', '/', $str); $str = base64_decode($str); $str = bin2hex($str); $str = str_split($str, 2); $binkey = md5($key); for($i=0;$i<(count($str)/16)+1;$i++){ 	$binkey .= md5($key.$binkey); } $binkey = str_split($binkey, 2); $returnment = ''; for ($i=0;$i<count($str);$i++){ 	$a = $str[$i]; 	$returnment .= ( 		pack('H*',  			pack('H*',  				bin2hex($a) 			) 		) 		^ 		pack('H*',  			pack('H*',  				bin2hex($binkey[$i]) 			) 		) 	); } return $returnment; 

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

Ну, вот и все.
Пример зашифрованной строки:
9tIxJAkLcPczhKURkE8YxK2F-WhkmlLcjoE08A==

Код на GitHub: https://github.com/da411d/Crypto228
Демка: http://app.blastorq.pp.ua/crypto228/

ссылка на оригинал статьи https://habrahabr.ru/post/279371/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *