RC4 encryption code snippet in VB5/VB6, C#, C++

26 01 2010

Hello again all.
In this post I thought I would include something many people ask me.

RC4 encryption in different languages.

Below is the code for RC4 encryption in VB.NET, C#, and c++ (written in visual c++)

C#

using System;
using System.Collections.Generic;
using System.IO;
namespace RC4Project
{
public class Rc4
{
private byte[] _S;
int _x, _y;
public Rc4()
{
}
public Rc4(byte[] key)
: this(key, key.Length)
{
}
public Rc4(byte[] key, int length)
{
SetKey(key, length);
}
public void SetKey(byte[] key)
{
SetKey(key, key.Length);
}
public void SetKey(byte[] key, int length)
{
if (_S == null)
_S = new byte[256];
if (key == null)
throw new ArgumentNullException("key");
if (length key.Length)
throw new ArgumentOutOfRangeException("length");
for (int i = 0; i < 256; i++)
_S[i] = (byte)i;
for (int i = 0, j = 0; i < 256; i++)
{
j = (j + key[i % length] + _S[i]) & 0xff;
byte temp = _S[i];
_S[i] = _S[j];
_S[j] = temp;
}
Reset();
}
public void Reset()
{
_x = _y = 0;
}
private byte GetNextMask()
{
_x = (_x + 1) & 0xff;
_y = (_y + _S[_x]) & 0xff;
byte temp = _S[_x];
_S[_x] = _S[_y];
_S[_y] = temp;
return _S[(_S[_x] + _S[_y]) & 0xff];
}
public IEnumerable Process(IEnumerable data)
{
if (data == null)
throw new ArgumentNullException("data");
if (_S == null)
throw new Exception("Need to call SetKey before calling Process");
foreach (byte b in data)
yield return (byte)(b ^ GetNextMask());
}
public void ProcessInPlace(byte[] data)
{
ProcessInPlace(data, 0, data.Length);
}
public void ProcessInPlace(byte[] data, int index, int length)
{
if (data == null)
throw new ArgumentNullException("data");
if (_S == null)
throw new Exception("Need to call SetKey before calling ProcessInPlace");
if (index = data.Length)
throw new ArgumentOutOfRangeException("index");
if (length data.Length)
throw new ArgumentOutOfRangeException("length");
for (int i = 0; i < length; i++)
data[i + index] = (byte)(data[i + index] ^ GetNextMask());
}
public byte[] Process(byte[] data)
{
return Process(data, 0, data.Length);
}
public byte[] Process(byte[] data, int index, int length)
{
if (data == null)
throw new ArgumentNullException("data");
if (_S == null)
throw new Exception("Need to call SetKey before calling Process");
if (index = data.Length)
throw new ArgumentOutOfRangeException("index");
if (length data.Length)
throw new ArgumentOutOfRangeException("length");
byte[] output = new byte[length];
for (int i = 0; i = 0)
output.WriteByte((byte)(databyte ^ GetNextMask()));
}
public void Process(Stream data, Stream output, long length)
{
if (length data.Length)
throw new ArgumentOutOfRangeException("length");
if (_S == null)
throw new Exception("Need to call SetKey before calling Process");
for (long i = 0; i < length; i++)
{
int databyte = data.ReadByte();
if (databyte < 0)
throw new EndOfStreamException("unexpected end of stream processing RC4");
output.WriteByte((byte)(databyte ^ GetNextMask()));
}
}
}
}

VB5/VB6 RC4 encryption

Public Function RC4(ByVal Expression As String, ByVal Password As String) As String
On Error Resume Next
Dim RB(0 To 255) As Integer, X As Long, Y As Long, Z As Long, Key() As Byte, ByteArray() As Byte, Temp As Byte
If Len(Password) = 0 Then
Exit Function
End If
If Len(Expression) = 0 Then
Exit Function
End If
If Len(Password) > 256 Then
Key() = StrConv(Left$(Password, 256), vbFromUnicode)
Else
Key() = StrConv(Password, vbFromUnicode)
End If
For X = 0 To 255
RB(X) = X
Next X
X = 0
Y = 0
Z = 0
For X = 0 To 255
Y = (Y + RB(X) + Key(X Mod Len(Password))) Mod 256
Temp = RB(X)
RB(X) = RB(Y)
RB(Y) = Temp
Next X
X = 0
Y = 0
Z = 0
ByteArray() = StrConv(Expression, vbFromUnicode)
For X = 0 To Len(Expression)
Y = (Y + 1) Mod 256
Z = (Z + RB(Y)) Mod 256
Temp = RB(Y)
RB(Y) = RB(Z)
RB(Z) = Temp
ByteArray(X) = ByteArray(X) Xor (RB((RB(Y) + RB(Z)) Mod 256))
Next X
RC4 = StrConv(ByteArray, vbUnicode)
End Function

C++ RC4 Encryption

void rc4(unsigned char * ByteInput, unsigned char * pwd,
unsigned char * &ByteOutput){
unsigned char * temp;
int i,j=0,t,tmp,tmp2,s[256], k[256];
for (tmp=0;tmp<256;tmp++){
s[tmp]=tmp;
k[tmp]=pwd[(tmp % strlen((char *)pwd))];
}
for (i=0;i<256;i++){
j = (j + s[i] + k[i]) % 256;
tmp=s[i];
s[i]=s[j];
s[j]=tmp;
}
temp = new unsigned char [ (int)strlen((char *)ByteInput) + 1 ] ;
i=j=0;
for (tmp=0;tmp<(int)strlen((char *)ByteInput);tmp++){
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp2=s[i];
s[i]=s[j];
s[j]=tmp2;
t = (s[i] + s[j]) % 256;
if (s[t]==ByteInput[tmp])
temp[tmp]=ByteInput[tmp];
else
temp[tmp]=s[t]^ByteInput[tmp];
}
temp[tmp]='';
ByteOutput=temp;
}

I'm not saying all this code is fool-proof and noob-friendly. I just quickly whipped it up. but I hope it has helped!

greets,
Raykoid666

About these ads

Actions

Information

One response

14 02 2010
Free Code Snippets

Thanks for these samples, very helpful!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: