📜 ⬆️ ⬇️

Just another bike encryption

Hi Habr!
From time to time I have the need to encrypt some data in my projects, but I don’t want to use ready-made solutions.
So I invented my bike. This is almost a simple XOR.

The problem of HOR encryption.


As wikipedia says,
The length of the gamma must not be less than the length of the message being protected (clear text). Otherwise, to obtain plaintext, you need to select the length of the gamma, analyze the ciphertext blocks of the correct length, and select the gamma bits.
Ie, if a key with a length at least equal to the length of the message is used, the XOR cipher becomes much more robust than using the key and is repeated. If a pseudo-random number generator is used to form such a key, the result will be a stream cipher.

I have something like a pseudo-random number generator.
And so, the encryption procedure:

1. The original string is converted to HEX, then split into 2 characters each.
$encoded = bin2hex($str); $encoded = str_split($encoded, 2); 

2. Generate the key
 $newkey = md5($key); for($i=0;$i<1000;$i++){ $newkey = $newkey.substr(md5($newkey.$i), 6, 1); } $key = $newkey;//   $binkey = ''; for($i=0;$i<(count($encoded)/16)+1;$i++){//         $binkey .= md5($key.$binkey.$secret.md5($i)); } $binkey = str_split($binkey, 2);//     2  

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

4. Convert back to binary data, then to base64. Replace base64 special characters
 $returnment = hex2bin($returnment); $returnment = base64_encode($returnment); $returnment = str_replace('+', '-', $returnment); $returnment = str_replace('/', '_', $returnment); 

')
Here's what we got:
 $secret = md5("VIKA").md5("ONE").md5("LOVE").md5("md5('!')").md5("SECRET_PASSWAD"); $encoded = bin2hex($str); $encoded = str_split($encoded, 2); $newkey = md5($key); for($i=0;$i<1000;$i++){ $newkey = $newkey.substr(md5($newkey.$i), 6, 1); } $key = $newkey; $binkey = ''; for($i=0;$i<(count($encoded)/16)+1;$i++){ $binkey .= md5($key.$binkey.$secret.md5($i)); } $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; 


We decrypt the same way.
 $secret = md5("VIKA").md5("ONE").md5("LOVE").md5("md5('!')").md5("SECRET_PASSWAD"); $str = str_replace('-', '+', $str); $str = str_replace('_', '/', $str); $str = base64_decode($str); $str = bin2hex($str); $str = str_split($str, 2); $newkey = md5($key); for($i=0;$i<1000;$i++){ $newkey = $newkey.substr(md5($newkey.$i), 6, 1); } $key = $newkey; $binkey = ''; for($i=0;$i<(count($str)/16)+1;$i++){ $binkey .= md5($key.$binkey.$secret.md5($i)); } $binkey = str_split($binkey, 2); $returnment = ''; for ($i=0;$i<count($str);$i++){ $a = $str[$i]; $returnment .= ( pack('H*', $a) ^ pack('H*', $binkey[$i]) ); } return $returnment; 

The reliability of encryption directly depends on the complexity of the key. Due to the fact that the password is hashed to just such a scheme ( see above ), this makes encryption very reliable IMHO.

Well that's all.
An example of an encrypted string:
0uo0XM5LX_OR_iwssLfV4NHPVdrV0l7vqXobjYOFqltJRdqPHz3hDnmPm8ibFRgEE_xgrLT4oN4 =

The code on GitHub is: https://github.com/da411d/Crypto228
Demo: http://app.blastorq.pp.ua/crypto228/

UPD: Updated the code, now for a couple of lines more govnokoda password is a thousand times hashes, and the “key stream” is now a little more complicated. There is also an additional master password.

Source: https://habr.com/ru/post/279371/


All Articles