Updated 06/11/05
Code: Select all
<?php
/******************************************************************************
* filename rc4.cls.php
* description RC4 stream encryption
*
* project AppEngine
* author redmonkey
* status alpha
*
* depends none
*
* license GPL, the GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html
*
* copyright 2005 redmonkey
*
* note passes all vector tests that I could find and throw at it so far
* which is not that many!
*
* note you may want to wrap base64 or some such similar around this for
* ease of use when dealing with the encrypted strings i.e.
* base64_encode(RC4::crypt($p, $d)) and
* RC4::crypt($p, base64_decode($d))
*
* history
* 03/11/05 v0.1 - initial version
* 04/11/05 v0.2 - added the storing of key in static variable which
* had mysteriously disappeared?
* 04/11/05 v0.2 - performance increase by removing calls to substr()
*
* notice RC4 is a registered trademark of the RSA Data Security Inc.
* this is an implementation of the original algorithm. the author
* of this program is NOT the original publisher of this algorithm.
*
* notice this program is free software, you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version
*
* notice this program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
******************************************************************************/
class RC4
{
/**
* @return array s
* @param string p the key string/phrase used for encryption
* @desc initialises the sbox array for the given key
*/
function init($p)
{
// the real paranoid may wish to change this so that the key is never
// held in memory for any longer than it needs to be
static $sp = '', $s = array();
if ($sp == $p)
{
return $s;
}
$sp = $p;
$plen = strlen($p);
for ($i = 0; $i < 256; $i++)
{
$a[$i] = ord($p{$i % $plen});
$s[$i] = $i;
}
unset($p);
for ($i = 0, $j = 0; $i < 256; $i++)
{
$j = ($j + $s[$i] + $a[$i]) % 256;
$t = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $t;
}
return $s;
}
/**
* @return string c encrypted data if $d is plain text,
* decrypted data if $d is encrypted
* @param string p the key string/phrase used for encryption
* @param string d plain text or encrypted stream
* @desc despite the function name, this will encrypt
* or decrypt $d based on the contents of $p
* if $d is encrypted the non encrypted string
* will be returned. If $d is plain text the
* encrypted string will be returned
*/
function crypt($p, $d)
{
$c = '';
$s = RC4::init($p);
unset($p);
// one of those rare occasions where i've been sorely tempted to use $l
for ($i = 0, $j = 0, $k = 0, $len = strlen($d); $i < $len; $i++)
{
$j = ($j + 1) % 256;
$k = ($k + $s[$j]) % 256;
$t = $s[$j];
$s[$j] = $s[$k];
$s[$k] = $t;
$c .= chr(ord($d{$i}) ^ $s[($s[$j] + $s[$k]) % 256]);
}
return $c;
}
}
?>Code: Select all
<?php
include('rc4.cls.php');
function strhex($string)
{
$hexval = '';
for ($i = 0, $len = strlen($string); $i < $len; $i++)
{
$hexval .= '0x' . str_pad(dechex(ord($string{$i})), 2, 0, STR_PAD_LEFT) . ', ';
}
return $hexval;
}
header('Content-Type: text/plain');
echo "RC4 Vector Tests \x0a\x0a";
echo "Test Vectors from [CRYPTLIB] : \x0a\x0a";
echo 'Text : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' . "\x0a\x0a";
echo 'Key : 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef' . "\x0a\x0a";
// CRYPTLIB
$data = "\x00\x00\x00\x00\x00\x00\x00\x00";
$key = "\x01\x23\x45\x67\x89\xab\xcd\xef";
echo 'Cipher : ';
echo substr(trim(strhex(RC4::crypt($key, $data))), 0, -1);
echo "\x0a\x0a";
echo "Test Vectors from [COMMERCE] : \x0a\x0a";
echo 'Text : 0xdc, 0xee, 0x4c, 0xf9, 0x2c' . "\x0a\x0a";
echo 'Key : 0x61, 0x8a, 0x63, 0xd2, 0xfb' . "\x0a\x0a";
// COMMERCE
$data = "\xdc\xee\x4c\xf9\x2c";
$key = "\x61\x8a\x63\xd2\xfb";
echo 'Cipher : ';
echo substr(trim(strhex(RC4::crypt($key, $data))), 0, -1);
echo "\x0a\x0a";
echo "Test Vectors from [SSH ARCFOUR] : \x0a\x0a";
echo "Text : 0x52, 0x75, 0x69, 0x73, 0x6c, 0x69, 0x6e, 0x6e,\x0a";
echo " 0x75, 0x6e, 0x20, 0x6c, 0x61, 0x75, 0x6c, 0x75,\x0a";
echo " 0x20, 0x6b, 0x6f, 0x72, 0x76, 0x69, 0x73, 0x73,\x0a";
echo " 0x73, 0x61, 0x6e, 0x69, 0x2c, 0x20, 0x74, 0xe4,\x0a";
echo " 0x68, 0x6b, 0xe4, 0x70, 0xe4, 0x69, 0x64, 0x65,\x0a";
echo " 0x6e, 0x20, 0x70, 0xe4, 0xe4, 0x6c, 0x6c, 0xe4,\x0a";
echo " 0x20, 0x74, 0xe4, 0x79, 0x73, 0x69, 0x6b, 0x75,\x0a";
echo " 0x75, 0x2e, 0x20, 0x4b, 0x65, 0x73, 0xe4, 0x79,\x0a";
echo " 0xf6, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x6e,\x0a";
echo " 0x6e, 0x69, 0x20, 0x6f, 0x6d, 0x61, 0x6e, 0x61,\x0a";
echo " 0x6e, 0x69, 0x2c, 0x20, 0x6b, 0x61, 0x73, 0x6b,\x0a";
echo " 0x69, 0x73, 0x61, 0x76, 0x75, 0x75, 0x6e, 0x20,\x0a";
echo " 0x6c, 0x61, 0x61, 0x6b, 0x73, 0x6f, 0x74, 0x20,\x0a";
echo " 0x76, 0x65, 0x72, 0x68, 0x6f, 0x75, 0x75, 0x2e,\x0a";
echo " 0x20, 0x45, 0x6e, 0x20, 0x6d, 0x61, 0x20, 0x69,\x0a";
echo " 0x6c, 0x6f, 0x69, 0x74, 0x73, 0x65, 0x2c, 0x20,\x0a";
echo " 0x73, 0x75, 0x72, 0x65, 0x20, 0x68, 0x75, 0x6f,\x0a";
echo " 0x6b, 0x61, 0x61, 0x2c, 0x20, 0x6d, 0x75, 0x74,\x0a";
echo " 0x74, 0x61, 0x20, 0x6d, 0x65, 0x74, 0x73, 0xe4,\x0a";
echo " 0x6e, 0x20, 0x74, 0x75, 0x6d, 0x6d, 0x75, 0x75,\x0a";
echo " 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x6c, 0x65, 0x20,\x0a";
echo " 0x74, 0x75, 0x6f, 0x6b, 0x61, 0x61, 0x2e, 0x20,\x0a";
echo " 0x50, 0x75, 0x75, 0x6e, 0x74, 0x6f, 0x20, 0x70,\x0a";
echo " 0x69, 0x6c, 0x76, 0x65, 0x6e, 0x2c, 0x20, 0x6d,\x0a";
echo " 0x69, 0x20, 0x68, 0x75, 0x6b, 0x6b, 0x75, 0x75,\x0a";
echo " 0x2c, 0x20, 0x73, 0x69, 0x69, 0x6e, 0x74, 0x6f,\x0a";
echo " 0x20, 0x76, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x74,\x0a";
echo " 0x75, 0x75, 0x6c, 0x69, 0x73, 0x65, 0x6e, 0x2c,\x0a";
echo " 0x20, 0x6d, 0x69, 0x20, 0x6e, 0x75, 0x6b, 0x6b,\x0a";
echo " 0x75, 0x75, 0x2e, 0x20, 0x54, 0x75, 0x6f, 0x6b,\x0a";
echo " 0x73, 0x75, 0x74, 0x20, 0x76, 0x61, 0x6e, 0x61,\x0a";
echo " 0x6d, 0x6f, 0x6e, 0x20, 0x6a, 0x61, 0x20, 0x76,\x0a";
echo " 0x61, 0x72, 0x6a, 0x6f, 0x74, 0x20, 0x76, 0x65,\x0a";
echo " 0x65, 0x6e, 0x2c, 0x20, 0x6e, 0x69, 0x69, 0x73,\x0a";
echo " 0x74, 0xe4, 0x20, 0x73, 0x79, 0x64, 0xe4, 0x6d,\x0a";
echo " 0x65, 0x6e, 0x69, 0x20, 0x6c, 0x61, 0x75, 0x6c,\x0a";
echo " 0x75, 0x6e, 0x20, 0x74, 0x65, 0x65, 0x6e, 0x2e,\x0a";
echo " 0x20, 0x2d, 0x20, 0x45, 0x69, 0x6e, 0x6f, 0x20,\x0a";
echo " 0x4c, 0x65, 0x69, 0x6e, 0x6f \x0a\x0a";
echo 'Key : 0x29, 0x04, 0x19, 0x72, 0xfb, 0x42, 0xba, 0x5f' . "\x0a";
echo ' 0xc7, 0x12, 0x77, 0x12, 0xf1, 0x38, 0x29, 0xc9' . "\x0a\x0a";
// SSH ARCFOUR
$data = "\x52\x75\x69\x73\x6c\x69\x6e\x6e"
. "\x75\x6e\x20\x6c\x61\x75\x6c\x75"
. "\x20\x6b\x6f\x72\x76\x69\x73\x73"
. "\x73\x61\x6e\x69\x2c\x20\x74\xe4"
. "\x68\x6b\xe4\x70\xe4\x69\x64\x65"
. "\x6e\x20\x70\xe4\xe4\x6c\x6c\xe4"
. "\x20\x74\xe4\x79\x73\x69\x6b\x75"
. "\x75\x2e\x20\x4b\x65\x73\xe4\x79"
. "\xf6\x6e\x20\x6f\x6e\x20\x6f\x6e"
. "\x6e\x69\x20\x6f\x6d\x61\x6e\x61"
. "\x6e\x69\x2c\x20\x6b\x61\x73\x6b"
. "\x69\x73\x61\x76\x75\x75\x6e\x20"
. "\x6c\x61\x61\x6b\x73\x6f\x74\x20"
. "\x76\x65\x72\x68\x6f\x75\x75\x2e"
. "\x20\x45\x6e\x20\x6d\x61\x20\x69"
. "\x6c\x6f\x69\x74\x73\x65\x2c\x20"
. "\x73\x75\x72\x65\x20\x68\x75\x6f"
. "\x6b\x61\x61\x2c\x20\x6d\x75\x74"
. "\x74\x61\x20\x6d\x65\x74\x73\xe4"
. "\x6e\x20\x74\x75\x6d\x6d\x75\x75"
. "\x73\x20\x6d\x75\x6c\x6c\x65\x20"
. "\x74\x75\x6f\x6b\x61\x61\x2e\x20"
. "\x50\x75\x75\x6e\x74\x6f\x20\x70"
. "\x69\x6c\x76\x65\x6e\x2c\x20\x6d"
. "\x69\x20\x68\x75\x6b\x6b\x75\x75"
. "\x2c\x20\x73\x69\x69\x6e\x74\x6f"
. "\x20\x76\x61\x72\x61\x6e\x20\x74"
. "\x75\x75\x6c\x69\x73\x65\x6e\x2c"
. "\x20\x6d\x69\x20\x6e\x75\x6b\x6b"
. "\x75\x75\x2e\x20\x54\x75\x6f\x6b"
. "\x73\x75\x74\x20\x76\x61\x6e\x61"
. "\x6d\x6f\x6e\x20\x6a\x61\x20\x76"
. "\x61\x72\x6a\x6f\x74\x20\x76\x65"
. "\x65\x6e\x2c\x20\x6e\x69\x69\x73"
. "\x74\xe4\x20\x73\x79\x64\xe4\x6d"
. "\x65\x6e\x69\x20\x6c\x61\x75\x6c"
. "\x75\x6e\x20\x74\x65\x65\x6e\x2e"
. "\x20\x2d\x20\x45\x69\x6e\x6f\x20"
. "\x4c\x65\x69\x6e\x6f";
$key = "\x29\x04\x19\x72\xfb\x42\xba\x5f"
. "\xc7\x12\x77\x12\xf1\x38\x29\xc9";
echo 'Cipher : ';
echo chunk_split(substr(trim(strhex(RC4::crypt($key, $data))), 0, -1), 48, "\x0a ");
?>Code: Select all
RC4 Vector Tests
Test Vectors from [CRYPTLIB] :
Text : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Key : 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
Cipher : 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79
Test Vectors from [COMMERCE] :
Text : 0xdc, 0xee, 0x4c, 0xf9, 0x2c
Key : 0x61, 0x8a, 0x63, 0xd2, 0xfb
Cipher : 0xf1, 0x38, 0x29, 0xc9, 0xde
Test Vectors from [SSH ARCFOUR] :
Text : 0x52, 0x75, 0x69, 0x73, 0x6c, 0x69, 0x6e, 0x6e,
0x75, 0x6e, 0x20, 0x6c, 0x61, 0x75, 0x6c, 0x75,
0x20, 0x6b, 0x6f, 0x72, 0x76, 0x69, 0x73, 0x73,
0x73, 0x61, 0x6e, 0x69, 0x2c, 0x20, 0x74, 0xe4,
0x68, 0x6b, 0xe4, 0x70, 0xe4, 0x69, 0x64, 0x65,
0x6e, 0x20, 0x70, 0xe4, 0xe4, 0x6c, 0x6c, 0xe4,
0x20, 0x74, 0xe4, 0x79, 0x73, 0x69, 0x6b, 0x75,
0x75, 0x2e, 0x20, 0x4b, 0x65, 0x73, 0xe4, 0x79,
0xf6, 0x6e, 0x20, 0x6f, 0x6e, 0x20, 0x6f, 0x6e,
0x6e, 0x69, 0x20, 0x6f, 0x6d, 0x61, 0x6e, 0x61,
0x6e, 0x69, 0x2c, 0x20, 0x6b, 0x61, 0x73, 0x6b,
0x69, 0x73, 0x61, 0x76, 0x75, 0x75, 0x6e, 0x20,
0x6c, 0x61, 0x61, 0x6b, 0x73, 0x6f, 0x74, 0x20,
0x76, 0x65, 0x72, 0x68, 0x6f, 0x75, 0x75, 0x2e,
0x20, 0x45, 0x6e, 0x20, 0x6d, 0x61, 0x20, 0x69,
0x6c, 0x6f, 0x69, 0x74, 0x73, 0x65, 0x2c, 0x20,
0x73, 0x75, 0x72, 0x65, 0x20, 0x68, 0x75, 0x6f,
0x6b, 0x61, 0x61, 0x2c, 0x20, 0x6d, 0x75, 0x74,
0x74, 0x61, 0x20, 0x6d, 0x65, 0x74, 0x73, 0xe4,
0x6e, 0x20, 0x74, 0x75, 0x6d, 0x6d, 0x75, 0x75,
0x73, 0x20, 0x6d, 0x75, 0x6c, 0x6c, 0x65, 0x20,
0x74, 0x75, 0x6f, 0x6b, 0x61, 0x61, 0x2e, 0x20,
0x50, 0x75, 0x75, 0x6e, 0x74, 0x6f, 0x20, 0x70,
0x69, 0x6c, 0x76, 0x65, 0x6e, 0x2c, 0x20, 0x6d,
0x69, 0x20, 0x68, 0x75, 0x6b, 0x6b, 0x75, 0x75,
0x2c, 0x20, 0x73, 0x69, 0x69, 0x6e, 0x74, 0x6f,
0x20, 0x76, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x74,
0x75, 0x75, 0x6c, 0x69, 0x73, 0x65, 0x6e, 0x2c,
0x20, 0x6d, 0x69, 0x20, 0x6e, 0x75, 0x6b, 0x6b,
0x75, 0x75, 0x2e, 0x20, 0x54, 0x75, 0x6f, 0x6b,
0x73, 0x75, 0x74, 0x20, 0x76, 0x61, 0x6e, 0x61,
0x6d, 0x6f, 0x6e, 0x20, 0x6a, 0x61, 0x20, 0x76,
0x61, 0x72, 0x6a, 0x6f, 0x74, 0x20, 0x76, 0x65,
0x65, 0x6e, 0x2c, 0x20, 0x6e, 0x69, 0x69, 0x73,
0x74, 0xe4, 0x20, 0x73, 0x79, 0x64, 0xe4, 0x6d,
0x65, 0x6e, 0x69, 0x20, 0x6c, 0x61, 0x75, 0x6c,
0x75, 0x6e, 0x20, 0x74, 0x65, 0x65, 0x6e, 0x2e,
0x20, 0x2d, 0x20, 0x45, 0x69, 0x6e, 0x6f, 0x20,
0x4c, 0x65, 0x69, 0x6e, 0x6f
Key : 0x29, 0x04, 0x19, 0x72, 0xfb, 0x42, 0xba, 0x5f
0xc7, 0x12, 0x77, 0x12, 0xf1, 0x38, 0x29, 0xc9
Cipher : 0x35, 0x81, 0x86, 0x99, 0x90, 0x01, 0xe6, 0xb5,
0xda, 0xf0, 0x5e, 0xce, 0xeb, 0x7e, 0xee, 0x21,
0xe0, 0x68, 0x9c, 0x1f, 0x00, 0xee, 0xa8, 0x1f,
0x7d, 0xd2, 0xca, 0xae, 0xe1, 0xd2, 0x76, 0x3e,
0x68, 0xaf, 0x0e, 0xad, 0x33, 0xd6, 0x6c, 0x26,
0x8b, 0xc9, 0x46, 0xc4, 0x84, 0xfb, 0xe9, 0x4c,
0x5f, 0x5e, 0x0b, 0x86, 0xa5, 0x92, 0x79, 0xe4,
0xf8, 0x24, 0xe7, 0xa6, 0x40, 0xbd, 0x22, 0x32,
0x10, 0xb0, 0xa6, 0x11, 0x60, 0xb7, 0xbc, 0xe9,
0x86, 0xea, 0x65, 0x68, 0x80, 0x03, 0x59, 0x6b,
0x63, 0x0a, 0x6b, 0x90, 0xf8, 0xe0, 0xca, 0xf6,
0x91, 0x2a, 0x98, 0xeb, 0x87, 0x21, 0x76, 0xe8,
0x3c, 0x20, 0x2c, 0xaa, 0x64, 0x16, 0x6d, 0x2c,
0xce, 0x57, 0xff, 0x1b, 0xca, 0x57, 0xb2, 0x13,
0xf0, 0xed, 0x1a, 0xa7, 0x2f, 0xb8, 0xea, 0x52,
0xb0, 0xbe, 0x01, 0xcd, 0x1e, 0x41, 0x28, 0x67,
0x72, 0x0b, 0x32, 0x6e, 0xb3, 0x89, 0xd0, 0x11,
0xbd, 0x70, 0xd8, 0xaf, 0x03, 0x5f, 0xb0, 0xd8,
0x58, 0x9d, 0xbc, 0xe3, 0xc6, 0x66, 0xf5, 0xea,
0x8d, 0x4c, 0x79, 0x54, 0xc5, 0x0c, 0x3f, 0x34,
0x0b, 0x04, 0x67, 0xf8, 0x1b, 0x42, 0x59, 0x61,
0xc1, 0x18, 0x43, 0x07, 0x4d, 0xf6, 0x20, 0xf2,
0x08, 0x40, 0x4b, 0x39, 0x4c, 0xf9, 0xd3, 0x7f,
0xf5, 0x4b, 0x5f, 0x1a, 0xd8, 0xf6, 0xea, 0x7d,
0xa3, 0xc5, 0x61, 0xdf, 0xa7, 0x28, 0x1f, 0x96,
0x44, 0x63, 0xd2, 0xcc, 0x35, 0xa4, 0xd1, 0xb0,
0x34, 0x90, 0xde, 0xc5, 0x1b, 0x07, 0x11, 0xfb,
0xd6, 0xf5, 0x5f, 0x79, 0x23, 0x4d, 0x5b, 0x7c,
0x76, 0x66, 0x22, 0xa6, 0x6d, 0xe9, 0x2b, 0xe9,
0x96, 0x46, 0x1d, 0x5e, 0x4d, 0xc8, 0x78, 0xef,
0x9b, 0xca, 0x03, 0x05, 0x21, 0xe8, 0x35, 0x1e,
0x4b, 0xae, 0xd2, 0xfd, 0x04, 0xf9, 0x46, 0x73,
0x68, 0xc4, 0xad, 0x6a, 0xc1, 0x86, 0xd0, 0x82,
0x45, 0xb2, 0x63, 0xa2, 0x66, 0x6d, 0x1f, 0x6c,
0x54, 0x20, 0xf1, 0x59, 0x9d, 0xfd, 0x9f, 0x43,
0x89, 0x21, 0xc2, 0xf5, 0xa4, 0x63, 0x93, 0x8c,
0xe0, 0x98, 0x22, 0x65, 0xee, 0xf7, 0x01, 0x79,
0xbc, 0x55, 0x3f, 0x33, 0x9e, 0xb1, 0xa4, 0xc1,
0xaf, 0x5f, 0x6a, 0x54, 0x7f