By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,751 Members | 1,175 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,751 IT Pros & Developers. It's quick & easy.

Encryption & Decryption script

P: n/a
I get bored last night and wrote a script that uses xor for encrypt-
decrypt, however it woks fine under linux 2.6.25, text and documents
are ok, but fails on compressed files *.jpg, *.pdf , etc . I didn't
test script on windows.

Here is the code, please send me your views.

<?php

/* Mother Eye Chipper with PHP :), Licence:GPL,
Author: Barış ÇUHADAR
Prepared to use in Console,
usage: "for encryption: php chipper.php -e <key<file>"
"for decryption: php chipper.php -d <key<file>" */

echo "A Basic Encryption & Decryption Program\n";
if(isset($argv[1]) && isset($argv[2]) && is_file($argv[3]) && $argv[3]!
=$_SERVER['PHP_SELF'])
{
$process = $argv[1];
$key = $argv[2];
$file = $argv[3];

if($process == "-e")
{
encrypt_file($file,$key);
}
else if($process == "-d")
{
decrypt_file($file,$key);
}
}
else
{
if($argc < 4)
echo "missing parameters\n \tdefault usage: php chipper.php [-e/-d]
<key<filename>\n";
else if(!is_file($argv[3]))
echo "file " . $argv[3] . " can not be found or is not a file\n";
else if($argv[3]==$_SERVER['PHP_SELF'])
echo "trying to encrypt own file\n";
else echo "unfortunately program is fubar\n";
}

/************************************************** **/
/* encryption begins */
function encrypt_file($file,$key)
{
$k = 0;
$fp_r = fopen($file,"rb");
$cont = fread($fp_r,12);
if($cont == "encrypted_so")
{
fclose($fp_r);
die("file is encrypted! can not be encrypted again!
\n");
}
while(!feof($fp_r))
{
$foo = fread($fp_r,65536);
for($i = 0; $i < strlen($foo); $i++)
{
$r[$i] = $foo[$i] ^ $key[$k];

if($k==sizeof($key))
$k = 0;
$k++;
}
$fp_w = fopen($file . "_temp","a");
/* encrypted content is being written on file*/
fwrite($fp_w,"encrypted_so");
for($i = 0; $i < sizeof($r); $i++)
fwrite($fp_w,$r[$i]);
fclose($fp_w);
$foo=null;
$k=0;
}
fclose($fp_r);
unlink($file);
rename($file . "_temp",$file);
echo "Encryption made successfully!\n";
}
/************************************************** **/
/* decryption */
function decrypt_file($file,$key)
{
$k = 0;
$fp_r = fopen($file,"rb");
$cont = fread($fp_r,12);
if($cont != "encrypted_so")
{
fclose($fp_r);
die("file is not encrypted! so can not
be decrypted..\n");
}
while(!feof($fp_r))
{
$r = fread($fp_r,65536);
for($i = 0; $i < strlen($r); $i++)
{
$foo[$i] = $r[$i] ^ $key[$k];

if($k==sizeof($key))
$k =0;
$k++;
}
/* decrypted content is being written on file */
$fp_w = fopen($file . "_temp","a");
for($i = 0; $i < sizeof($foo); $i++)
fwrite($fp_w,$foo[$i]);
fclose($fp_w);
}
fclose($fp_r);
unlink($file);
rename($file . "_temp",$file);
echo "Decryption made successfully!\n";
}

?>
Sep 30 '08 #1
Share this Question
Share on Google+
9 Replies


P: n/a
I get bored last night and wrote a script that uses xor for encrypt-
decrypt, however it woks fine under linux 2.6.25, text and documents
are ok, but fails on compressed files *.jpg, *.pdf , etc . I didn't
test script on windows.
I did not look at the code, but xor on PHP is quite counter-intuitive.
The most significant bit is seen as a sign bit and is treated special.
Furthermore, the size of an integer is not determined. I ended up
creating my own fixed size integer classes when I had to implement a
decryption algorithm.

Best regards,
--
Willem Bogaerts

Application smith
Kratz B.V.
http://www.kratz.nl/
Sep 30 '08 #2

P: n/a
^ (bitwise operator) is for ascii values, won't work on binary.
need to convert from binary to at least decimal or maybe hex before
xor. You'll have to break it up into 8 bits as well to get a valid
ascii character.

Sep 30 '08 #3

P: n/a
could try:

while(!feof($fp_r)) {

$r = fread($fp_r,65536);

if (is_binary($r)) {
$binArray = split('[0-1]{8}',$r); //or use \d{8}
$r = '';
foreach ($binArray as $value) {
$r .= bindec($value);
}
//Could use array_walk as well

for($i = 0; $i < strlen($r); $i++) {
$foo[$i] = $r[$i] ^ $key[$k];

if($k==sizeof($key))
$k =0;
$k++;
} .....
Sep 30 '08 #4

P: n/a
On Sep 30, 4:40*pm, The Hajj <hajji.hims...@gmail.comwrote:
^ (bitwise operator) is for ascii values, won't work on binary.
need to convert from binary to at least decimal or maybe hex before
xor. You'll have to break it up into 8 bits as well to get a valid
ascii character.
I cosidered that before but when read file as whole there is no
problem, using fread($fp,filesize($file) or file_get_contents($file).
However fread($fp,65536) or else makes the case, breaks the bit
block ;). For now i removed "encrypted_so" part...

<?php
define("READ_SIZE",1000000);
/* Mother Eye Chipper with PHP, Licence:GPL,
Author: Barış ÇUHADAR
Prepared to use in Console,
usage: "for encryption: php chipper.php -e <key<file>"
"for decryption: php chipper.php -d <key<file>" */
echo "A Basic Encryption & Decryption Program\n";
if(isset($argv[1]) && isset($argv[2]) && is_file($argv[3]) && $argv[3]!
=$_SERVER['PHP_SELF'])
{
$process = $argv[1];
$key = $argv[2];
$file = $argv[3];

if($process == "-e")
{
encrypt_file($file,$key);
}
else if($process == "-d")
{
decrypt_file($file,$key);
}
}
else
{
if($argc < 4)
echo "missing parameters\n \tdefault usage: php chipper.php [-e/-d]
<key<filename>\n";
else if(!is_file($argv[3]))
echo "file " . $argv[3] . " can not be found or is not a file\n";
else if($argv[3]==$_SERVER['PHP_SELF'])
echo "trying to encrypt own file\n";
else echo "unfortunately program is fubar\n";
}

/************************************************** **/
/* encryption begins */
function encrypt_file($file,$key)
{
$flag = false;
$k = 0;
$fp_r = fopen($file,"rb");
while(!feof($fp_r))
{
$foo = fread($fp_r,READ_SIZE);
for($i = 0; $i < strlen($foo); $i++)
{
$r[$i] = $foo[$i] ^ $key[$k];

if($k==sizeof($key))
$k = 0;
$k++;
}
$fp_w = fopen($file . "_temp","a");
/* encrypted content is being written on file*/
for($i = 0; $i < sizeof($r); $i++)
fwrite($fp_w,$r[$i]);
fclose($fp_w);
$foo=null;
$k=0;
}
fclose($fp_r);
unlink($file);
rename($file . "_temp",$file);
echo "Encryption made successfully!\n";
}
/************************************************** **/
/* decryption */
function decrypt_file($file,$key)
{
$k = 0;
$fp_r = fopen($file,"rb");
while(!feof($fp_r))
{
$r = fread($fp_r,READ_SIZE);
for($i = 0; $i < strlen($r); $i++)
{
$foo[$i] = $r[$i] ^ $key[$k];

if($k==sizeof($key))
$k =0;
$k++;
}
/* decrypted content is being written on file */
$fp_w = fopen($file . "_temp","a");
for($i = 0; $i < sizeof($foo); $i++)
fwrite($fp_w,$foo[$i]);
fclose($fp_w);
}
fclose($fp_r);
unlink($file);
rename($file . "_temp",$file);
echo "Decryption made successfully!\n";
}

?>
Sep 30 '08 #5

P: n/a
..oO(The Hajj)
>^ (bitwise operator) is for ascii values, won't work on binary.
Huh? Where did you get that from? What's the difference between an ASCII
byte and a binary byte?
>need to convert from binary to at least decimal
If you read a byte from somewhere it _is_ decimal, it's always a numeric
value between 0..255. Of course you can interpret it in different ways.

Micha
Sep 30 '08 #6

P: n/a
..oO(Betikci Boris)
>I get bored last night and wrote a script that uses xor for encrypt-
decrypt, however it woks fine under linux 2.6.25, text and documents
are ok, but fails on compressed files *.jpg, *.pdf , etc . I didn't
test script on windows.

Here is the code, please send me your views.
[...]
There are some logical flaws in the code and I'm wondering if it worked
at all:

* The encrypt_file() function reads the first 12 bytes to check if the
file is already encrypted, but then doesn't jump back to the beginning
of the file when the encryption process starts.

* With bigger files you'll end up with the string 'encrypted_so' being
scattered across the entire file, because your encryption loop may open
and close the target file multiple times and will write that string
before every chunk of 64K.

* These lines

if ($k == sizeof($key))
$k = 0;
$k++;

will cause E_NOTICE errors after the first run of the loop. From there
on the first char of the key will be ignored. Additionally sizeof() is
an alias for count(), which only works on arrays, not on strings. So it
should be something like

$k++;
if ($k == strlen($key)) {
$k = 0;
}

instead.

But IMHO the biggest problem is that you use strlen() on binary data.
This function should not be considered binary-safe! If the Multibyte
extension is enabled, strlen() might be overloaded with mb_strlen().
This means that it tries to work on chars, not on bytes anymore. If you
compare the output of strlen() and filesize() of a small binary file,
you'll most likely get different results. To solve this issue, you could
use a little helper function like this to get the real binary size:

function strSize($string) {
return extension_loaded('mbstring')
? mb_strlen($string, '8bit')
: strlen($string);
}

You should also consider to move the encryption/decryption part to a
seperate function, because the algorithm is the same. With some little
improvements it may look like this:

function codec($fp_r, $fp_w, $key) {
$keySize = strSize($key);
$k = 0;
while (!feof($fp_r)) {
$data = fread($fp_r, 65536);
$result = '';
for ($i = 0, $c = strSize($data); $i < $c; $i++) {
$result .= $data[$i] ^ $key[$k];
$k++;
if ($k == $keySize) {
$k = 0;
}
}
fwrite($fp_w, $result);
}
}

Given these two little helpers, your main functions may now look like
this (I've restructured the code a bit to make it more readable for me):

function encrypt_file($file, $key) {
$fp_r = fopen($file, 'rb');
if (fread($fp_r, 12) == 'encrypted_so') {
fclose($fp_r);
die("file is encrypted! can not be encrypted again!\n");
}
fseek($fp_r, 0);
$fp_w = fopen("{$file}_temp", 'wb');
fwrite($fp_w, 'encrypted_so');
codec($fp_r, $fp_w, $key);
fclose($fp_r);
fclose($fp_w);
unlink($file);
rename("{$file}_temp", $file);
echo "Encryption made successfully!\n";
}

function decrypt_file($file, $key) {
$fp_r = fopen($file, 'rb');
if (fread($fp_r, 12) != 'encrypted_so') {
fclose($fp_r);
die("file is not encrypted! so can not be decrypted..\n");
}
$fp_w = fopen("{$file}_temp", 'wb');
codec($fp_r, $fp_w, $key);
fclose($fp_r);
fclose($fp_w);
unlink($file);
rename("{$file}_temp", $file);
echo "Decryption made successfully!\n";
}

Tested on a small text file, a GIF and an MP3. All worked well.

HTH
Micha
Sep 30 '08 #7

P: n/a
..oO(Willem Bogaerts)
>I get bored last night and wrote a script that uses xor for encrypt-
decrypt, however it woks fine under linux 2.6.25, text and documents
are ok, but fails on compressed files *.jpg, *.pdf , etc . I didn't
test script on windows.

I did not look at the code, but xor on PHP is quite counter-intuitive.
The most significant bit is seen as a sign bit and is treated special.
Can you elaborate on that or give an example?

<?php
$foo = 129; // 10000001b
$bar = 66; // 01000010b
$huh = 200; // 11001000b
var_dump(decbin($foo ^ $bar)); // 11000011b
var_dump(decbin($foo ^ $huh)); // 01001001b
var_dump(decbin($bar ^ $huh)); // 10001010b
var_dump(decbin($foo ^ $bar ^ $huh)); // 00001011b
?>

All as expected.

Micha
Sep 30 '08 #8

P: n/a
On Sep 30, 6:58*pm, Michael Fesser <neti...@gmx.dewrote:
.oO(Betikci Boris)
I get bored last night and wrote a script that uses xor for encrypt-
decrypt, however it woks fine under linux 2.6.25, text and documents
are ok, but fails on compressed files *.jpg, *.pdf , etc . I didn't
test script on windows.
Here is the code, please send me your views.
[...]

There are some logical flaws in the code and I'm wondering if it worked
at all:

* The encrypt_file() function reads the first 12 bytes to check if the
file is already encrypted, but then doesn't jump back to the beginning
of the file when the encryption process starts.

* With bigger files you'll end up with the string 'encrypted_so' being
scattered across the entire file, because your encryption loop may open
and close the target file multiple times and will write that string
before every chunk of 64K.

* These lines

* if ($k == sizeof($key))
* * $k = 0;
* $k++;

will cause E_NOTICE errors after the first run of the loop. From there
on the first char of the key will be ignored. Additionally sizeof() is
an alias for count(), which only works on arrays, not on strings. So it
should be something like

* $k++;
* if ($k == strlen($key)) {
* * $k = 0;
* }

instead.

But IMHO the biggest problem is that you use strlen() on binary data.
This function should not be considered binary-safe! If the Multibyte
extension is enabled, strlen() might be overloaded with mb_strlen().
This means that it tries to work on chars, not on bytes anymore. If you
compare the output of strlen() and filesize() of a small binary file,
you'll most likely get different results. To solve this issue, you could
use a little helper function like this to get the real binary size:

* function strSize($string) {
* * return extension_loaded('mbstring')
* * * ? mb_strlen($string, '8bit')
* * * : strlen($string);
* }

You should also consider to move the encryption/decryption part to a
seperate function, because the algorithm is the same. With some little
improvements it may look like this:

* function codec($fp_r, $fp_w, $key) {
* * $keySize = strSize($key);
* * $k = 0;
* * while (!feof($fp_r)) {
* * * $data = fread($fp_r, 65536);
* * * $result = '';
* * * for ($i = 0, $c = strSize($data); $i < $c; $i++) {
* * * * $result .= $data[$i] ^ $key[$k];
* * * * $k++;
* * * * if ($k == $keySize) {
* * * * * $k = 0;
* * * * }
* * * }
* * * fwrite($fp_w, $result);
* * }
* }

Given these two little helpers, your main functions may now look like
this (I've restructured the code a bit to make it more readable for me):

* function encrypt_file($file, $key) {
* * $fp_r = fopen($file, 'rb');
* * if (fread($fp_r, 12) == 'encrypted_so') {
* * * fclose($fp_r);
* * * die("file is encrypted! can not be encrypted again!\n");
* * }
* * fseek($fp_r, 0);
* * $fp_w = fopen("{$file}_temp", 'wb');
* * fwrite($fp_w, 'encrypted_so');
* * codec($fp_r, $fp_w, $key);
* * fclose($fp_r);
* * fclose($fp_w);
* * unlink($file);
* * rename("{$file}_temp", $file);
* * echo "Encryption made successfully!\n";
* }

* function decrypt_file($file, $key) {
* * $fp_r = fopen($file, 'rb');
* * if (fread($fp_r, 12) != 'encrypted_so') {
* * * fclose($fp_r);
* * * die("file is not encrypted! so can not be decrypted..\n");
* * }
* * $fp_w = fopen("{$file}_temp", 'wb');
* * codec($fp_r, $fp_w, $key);
* * fclose($fp_r);
* * fclose($fp_w);
* * unlink($file);
* * rename("{$file}_temp", $file);
* * echo "Decryption made successfully!\n";
* }

Tested on a small text file, a GIF and an MP3. All worked well.

HTH
Micha
Thank you Micha! which i forgotten was fseek($fp_r,0);

Additionally, i did't understand difference between,
$k++;
if ($k == strlen($key)) {
$k = 0;
}
and

if ($k == strlen($key)) {
$k = 0;
}
$k++;

Plus =)
$flag = true;
//...
if($flag)
{
fwrite($fp_w,"encrypted_so");
$flag = false;
}

is needed in my code, but you clearified the code very well, thanks
again ;)
Sep 30 '08 #9

P: n/a
..oO(Betikci Boris)
>[...]
is needed in my code, but you clearified the code very well, thanks
again ;)
You're welcome.

Micha
Sep 30 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.