Instantly share code, notes, and snippets.

Embed
What would you like to do?
RC4 encryption in javascript and php
/*
* RC4 symmetric cipher encryption/decryption
*
* @license Public Domain
* @param string key - secret key for encryption/decryption
* @param string str - string to be encrypted/decrypted
* @return string
*/
function rc4(key, str) {
var s = [], j = 0, x, res = '';
for (var i = 0; i < 256; i++) {
s[i] = i;
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
x = s[i];
s[i] = s[j];
s[j] = x;
}
i = 0;
j = 0;
for (var y = 0; y < str.length; y++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
x = s[i];
s[i] = s[j];
s[j] = x;
res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
}
return res;
}
<?php
/*
* RC4 symmetric cipher encryption/decryption
*
* @license Public Domain
* @param string key - secret key for encryption/decryption
* @param string str - string to be encrypted/decrypted
* @return string
*/
function rc4($key, $str) {
$s = array();
for ($i = 0; $i < 256; $i++) {
$s[$i] = $i;
}
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $s[$i] + ord($key[$i % strlen($key)])) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;
}
$i = 0;
$j = 0;
$res = '';
for ($y = 0; $y < strlen($str); $y++) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;
$res .= $str[$y] ^ chr($s[($s[$i] + $s[$j]) % 256]);
}
return $res;
}
?>
@WebReflection

This comment has been minimized.

Show comment
Hide comment
@WebReflection

WebReflection Sep 12, 2012

just wonder if this, or its source ... was actually inspired by this one: http://code.google.com/p/sessionstorage/source/browse/trunk/src/RC4.js

WebReflection commented Sep 12, 2012

just wonder if this, or its source ... was actually inspired by this one: http://code.google.com/p/sessionstorage/source/browse/trunk/src/RC4.js

@farhadi

This comment has been minimized.

Show comment
Hide comment
@farhadi

farhadi Mar 7, 2013

Well, different implementations of the same algorithm couldn't be much different.
Actually I wrote this code about 7 years ago based on some pseudocode in an article about RC4 (which I don't remember where I found) and published it in my personal website:
http://web.archive.org/web/20060810225251/http://farhadi.ir/rc4.html

Owner

farhadi commented Mar 7, 2013

Well, different implementations of the same algorithm couldn't be much different.
Actually I wrote this code about 7 years ago based on some pseudocode in an article about RC4 (which I don't remember where I found) and published it in my personal website:
http://web.archive.org/web/20060810225251/http://farhadi.ir/rc4.html

@Madhavarao

This comment has been minimized.

Show comment
Hide comment
@Madhavarao

Madhavarao Apr 5, 2013

Is it possible to get java compatible algorithm for the same?

Madhavarao commented Apr 5, 2013

Is it possible to get java compatible algorithm for the same?

@farhadi

This comment has been minimized.

Show comment
Hide comment
@farhadi

farhadi Apr 5, 2013

I'm not a Java developer but the code is simple and I think an average Java programmer can port it to Java.

Owner

farhadi commented Apr 5, 2013

I'm not a Java developer but the code is simple and I think an average Java programmer can port it to Java.

@basgroot

This comment has been minimized.

Show comment
Hide comment
@basgroot

basgroot Jun 15, 2013

Javascript works, but PHP code doesn't work with unicode strings, like '€'.

basgroot commented Jun 15, 2013

Javascript works, but PHP code doesn't work with unicode strings, like '€'.

@basgroot

This comment has been minimized.

Show comment
Hide comment
@basgroot

basgroot Jun 15, 2013

It looks like there is a difference in the last line of the PHP version, compared to JS:
JS: res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
PHP: $res .= $str[$y] ^ chr($s[($s[$i] + $s[$j]) % 256]);

This is my PHP version, which works with unicode, at least on my server:

function mb_chr($char) {
return mb_convert_encoding('&#'.intval($char).';', 'UTF-8', 'HTML-ENTITIES');
}

function mb_ord($char) {
$result = unpack('N', mb_convert_encoding($char, 'UCS-4BE', 'UTF-8'));

if (is_array($result) === true) {
return $result[1];
}
return ord($char);
}

function rc4($key, $str) {
if (extension_loaded('mbstring') === true) {
mb_language('Neutral');
mb_internal_encoding('UTF-8');
mb_detect_order(array('UTF-8', 'ISO-8859-15', 'ISO-8859-1', 'ASCII'));
}

$s = array();
for ($i = 0; $i < 256; $i++) {
$s[$i] = $i;
}
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $s[$i] + mb_ord(mb_substr($key, $i % mb_strlen($key), 1))) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;
}
$i = 0;
$j = 0;
$res = '';
for ($y = 0; $y < mb_strlen($str); $y++) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;

$res .= mb_chr(mb_ord(mb_substr($str, $y, 1)) ^ $s[($s[$i] + $s[$j]) % 256]);

}
return $res;
}

basgroot commented Jun 15, 2013

It looks like there is a difference in the last line of the PHP version, compared to JS:
JS: res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
PHP: $res .= $str[$y] ^ chr($s[($s[$i] + $s[$j]) % 256]);

This is my PHP version, which works with unicode, at least on my server:

function mb_chr($char) {
return mb_convert_encoding('&#'.intval($char).';', 'UTF-8', 'HTML-ENTITIES');
}

function mb_ord($char) {
$result = unpack('N', mb_convert_encoding($char, 'UCS-4BE', 'UTF-8'));

if (is_array($result) === true) {
return $result[1];
}
return ord($char);
}

function rc4($key, $str) {
if (extension_loaded('mbstring') === true) {
mb_language('Neutral');
mb_internal_encoding('UTF-8');
mb_detect_order(array('UTF-8', 'ISO-8859-15', 'ISO-8859-1', 'ASCII'));
}

$s = array();
for ($i = 0; $i < 256; $i++) {
$s[$i] = $i;
}
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $s[$i] + mb_ord(mb_substr($key, $i % mb_strlen($key), 1))) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;
}
$i = 0;
$j = 0;
$res = '';
for ($y = 0; $y < mb_strlen($str); $y++) {
$i = ($i + 1) % 256;
$j = ($j + $s[$i]) % 256;
$x = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $x;

$res .= mb_chr(mb_ord(mb_substr($str, $y, 1)) ^ $s[($s[$i] + $s[$j]) % 256]);

}
return $res;
}

@reyneke-vosz

This comment has been minimized.

Show comment
Hide comment
@reyneke-vosz

reyneke-vosz Jul 23, 2013

Thats exactly what i need! PHP-Decryption and JS-Encryption. In my case I had to utf8_encode the decrypted string. Works fine, thanks!

reyneke-vosz commented Jul 23, 2013

Thats exactly what i need! PHP-Decryption and JS-Encryption. In my case I had to utf8_encode the decrypted string. Works fine, thanks!

@eduardoalcantara

This comment has been minimized.

Show comment
Hide comment
@eduardoalcantara

eduardoalcantara Jul 24, 2013

I need encryption and decryption for at least PHP.

eduardoalcantara commented Jul 24, 2013

I need encryption and decryption for at least PHP.

@r3wt

This comment has been minimized.

Show comment
Hide comment
@r3wt

r3wt May 14, 2014

i need php encryption and js decryption for websocket messages

r3wt commented May 14, 2014

i need php encryption and js decryption for websocket messages

@DamilolaJegede

This comment has been minimized.

Show comment
Hide comment
@DamilolaJegede

DamilolaJegede Jul 16, 2014

But this is one-way. How about the snippet for decryption?

DamilolaJegede commented Jul 16, 2014

But this is one-way. How about the snippet for decryption?

@burn0050

This comment has been minimized.

Show comment
Hide comment
@burn0050

burn0050 Nov 11, 2014

Actually, @DamilolaJegede, this function is symmetrical. If you pass the resulting (encoded) string back into the function, you get the original string back.

burn0050 commented Nov 11, 2014

Actually, @DamilolaJegede, this function is symmetrical. If you pass the resulting (encoded) string back into the function, you get the original string back.

@MrsSahsirao

This comment has been minimized.

Show comment
Hide comment
@MrsSahsirao

MrsSahsirao May 5, 2015

how to combine this rc4 with Message Authentication code?

MrsSahsirao commented May 5, 2015

how to combine this rc4 with Message Authentication code?

@aldoemilio

This comment has been minimized.

Show comment
Hide comment
@aldoemilio

aldoemilio May 2, 2016

Hi Basgroot, I need to encript a series of _GET values before including them in the URL, and decript them in the target page in order to populate it, with the various _GET values. But the function does not decript the string as pairs of GET keys and values. How can I achieve this?

aldoemilio commented May 2, 2016

Hi Basgroot, I need to encript a series of _GET values before including them in the URL, and decript them in the target page in order to populate it, with the various _GET values. But the function does not decript the string as pairs of GET keys and values. How can I achieve this?

@weeco

This comment has been minimized.

Show comment
Hide comment
@weeco

weeco Aug 20, 2017

Why is there no support for streaming? Or at least keeping the internal state?
Can you add that please?

RC4 is a stream cipher so there has to be support for transforming data while keeping the internal state of the encryption/decryption SBox (https://en.wikipedia.org/wiki/RC4 see: Key scheduling)

weeco commented Aug 20, 2017

Why is there no support for streaming? Or at least keeping the internal state?
Can you add that please?

RC4 is a stream cipher so there has to be support for transforming data while keeping the internal state of the encryption/decryption SBox (https://en.wikipedia.org/wiki/RC4 see: Key scheduling)

@weeco

This comment has been minimized.

Show comment
Hide comment
@weeco

weeco Aug 20, 2017

nevermind, this one does the trick
https://www.npmjs.com/package/simple-rc4
;-)

weeco commented Aug 20, 2017

nevermind, this one does the trick
https://www.npmjs.com/package/simple-rc4
;-)

@jesobreira

This comment has been minimized.

Show comment
Hide comment
@jesobreira

jesobreira Nov 10, 2017

Here's my port to AutoIt3:

Func rc4($sKey, $sStr)
	Local $s[256], $j = 0, $x, $res, $y, $i
	Local $uBound
	For $i = 0 To 255
		$s[$i] = $i
	Next
	For $i = 0 To 255
		$j = Mod(($j + $s[$i] + Asc(StringMid($sKey, Mod($i, StringLen($sKey))+1, 1))), 256)
		$x = $s[$i]
		$s[$i] = $s[$j]
		$s[$j] = $x
	Next
	$i = 0
	$j = 0
	For $y = 0 To StringLen($sStr)-1
		$i = Mod(($i + 1), 256)
		$j = Mod(($j + $s[$i]), 256)
		$x = $s[$i]
		$s[$i] = $s[$j]
		$s[$j] = $x
		$res &= Chr(BitXOR(Asc(StringMid($sStr, $y+1, 1)), ($s[Mod(($s[$i] + $s[$j]), 256)])))
	Next
	Return $res
EndFunc

jesobreira commented Nov 10, 2017

Here's my port to AutoIt3:

Func rc4($sKey, $sStr)
	Local $s[256], $j = 0, $x, $res, $y, $i
	Local $uBound
	For $i = 0 To 255
		$s[$i] = $i
	Next
	For $i = 0 To 255
		$j = Mod(($j + $s[$i] + Asc(StringMid($sKey, Mod($i, StringLen($sKey))+1, 1))), 256)
		$x = $s[$i]
		$s[$i] = $s[$j]
		$s[$j] = $x
	Next
	$i = 0
	$j = 0
	For $y = 0 To StringLen($sStr)-1
		$i = Mod(($i + 1), 256)
		$j = Mod(($j + $s[$i]), 256)
		$x = $s[$i]
		$s[$i] = $s[$j]
		$s[$j] = $x
		$res &= Chr(BitXOR(Asc(StringMid($sStr, $y+1, 1)), ($s[Mod(($s[$i] + $s[$j]), 256)])))
	Next
	Return $res
EndFunc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment