12,502,578 members (56,278 online)
alternative version

44.6K views
34 bookmarked
Posted

# Two Efficient Classes for RC4 and Base64 Stream Cipher Algorithms

, 15 Apr 2009 CPOL
 Rate this:
Two fast and efficient classes of RC4 and Base64 stream cipher algorithms

## Introduction

This article provides two efficient and handy wrapping C++ classes of Base64 and RC4 stream cipher algorithms.

## Background

I programmed the classes after I searched the internet and found very few implementations are neat and efficient enough for practical use as lower cipher classes in the project.

## Introduction of Algorithms

#### What is RC4

RC4 was created by Ron Rivest of RSA Security in 1987. It is one of the most widely-used software stream cipher and is used in popular protocols such as Secure Sockets Layer (SSL) (to protect Internet traffic) and WEP (to secure wireless networks). RC4 is used in many commercial software packages such as Lotus Notes and Oracle Secure SQL.

There are two parts in RC4 algorithm, a 'key scheduling algorithm' (KSA) which turns a random key (typically between 40 and 256 bits) into an initial permutation of S-box of N(power of 2). The other part is 'pseudorandom number generator(' PRNG), PRNG uses the permutation to generate a pseudo-random number sequence which is XORed with the plaintext to give the cipher text.

RC4 is a fast cipher algorithm and about 10 times faster than DES(Data Encryption Standard).

This wrapping class CRC4 is a handy version for using by avoiding string terminator ¡®\0¡¯ in the middle of the encoded text data. It is annoying and bug-hidden if you want to handle the encoded text data as a `string` without knowing that the '\0' character could truncate your cipher text to be incomplete.

#### The Code of Class CRC4

```#define SWAP(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
class CRC4
{
public:

CRC4 ()
{
memset(sbox,0,256);
memset(key,0,256);
}
virtual ~CRC4 ()
{
memset(sbox,0,256);  /* remove Key traces in memory  */
memset(key,0,256);
}

char *Encrypt(char *pszText,const char *pszKey)
{
i=0, j=0,n = 0;
ilen = (int)strlen(pszKey);

for (m = 0;  m < 256; m++)  /* Initialize the key sequence */
{
*(key + m)= *(pszKey + (m % ilen));
*(sbox + m) = m;
}
for (m=0; m < 256; m++)
{
n = (n + *(sbox+m) + *(key + m)) &0xff;
SWAP(*(sbox + m),*(sbox + n));
}

ilen = (int)strlen(pszText);
for (m = 0; m < ilen; m++)
{
i = (i + 1) &0xff;
j = (j + *(sbox + i)) &0xff;
SWAP(*(sbox+i),*(sbox + j));  /* randomly Initialize
the key sequence */
k = *(sbox + ((*(sbox + i) + *(sbox + j)) &0xff ));
if(k == *(pszText + m))       /* avoid '\0' among the
encoded text; */
k = 0;
*(pszText + m) ^=  k;
}

return pszText;
}

char *Decrypt(char *pszText,const char *pszKey)
{
return Encrypt(pszText,pszKey) ;  /* using the same function
as encoding */
}

private:
unsigned char sbox[256];      /* Encryption array             */
unsigned char key[256],k;     /* Numeric key values           */
int  m, n, i, j, ilen;        /* Ambiguously named counters   */
};
;```

#### What is BASE64

Base64 is a different way of interpreting bits of data in order to transmit that data over a text-only medium, such as the body of an e-mail.

The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable. It is widely used in e-mail encoding and also .NET View state encoding for its efficiency.

Base64 algorithm processes input in 24bit chunks by converting each chunk into 4 bytes of output. It does so by splitting input into four 6 bit groups and using these as indexes in the following substitution table:

```const char base64_map[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";```

If an input is not a multiple of 3 bytes, it's padded with zeros. In this case, the output bytes that consist entirely of the pad data are replaced with '='.

##### Example of Base64

An input of `0x00 0x45 0xF2 `is equivalent to `00000000 01000101 11110010 `bit sequence, which is then split into `000000 000100 010111 110010 `and these are substituted to produce the following base64 encoding 'A' 'E' 'X' 'y'.

#### The code of class CBase64

```class CBase64
{
public:
CBase64(){}

char *Encrypt(const char * srcp, int len, char * dstp)
{
register int i = 0;
char *dst = dstp;

for (i = 0; i < len - 2; i += 3)
{
*dstp++ = *(base64_map + ((*(srcp+i)>>2)&0x3f));
*dstp++ = *(base64_map + ((*(srcp+i)<< 4)&0x30 | (
*(srcp+i+1)>>4)&0x0f ));
*dstp++ = *(base64_map + ((*(srcp+i+1)<<2)&0x3C | (
*(srcp+i+2)>>6)&0x03));
*dstp++ = *(base64_map + (*(srcp+i+2)&0x3f));
}
srcp += i;
len -= i;

if(len & 0x02 ) /* (i==2) 2 bytes left,pad one byte of '=' */
{
*dstp++ = *(base64_map + ((*srcp>>2)&0x3f));
*dstp++ = *(base64_map + ((*srcp<< 4)&0x30 | (
*(srcp+1)>>4)&0x0f ));
*dstp++ = *(base64_map + ((*(srcp+1)<<2)&0x3C) );
*dstp++ = '=';
}
else if(len & 0x01 )  /* (i==1) 1 byte left,pad two bytes of '='  */
{
*dstp++ = *(base64_map + ((*srcp>>2)&0x3f));
*dstp++ = *(base64_map + ((*srcp<< 4)&0x30));
*dstp++ = '=';
*dstp++ = '=';
}

*dstp = '\0';

return dst;
}

void *Decrypt(const char * srcp, int len, char * dstp)
{
register int i = 0;
void *dst = dstp;

while(i < len)
{
*dstp++ = (B64_offset[*(srcp+i)] <<2 |
B64_offset[*(srcp+i+1)] >>4);
*dstp++ = (B64_offset[*(srcp+i+1)]<<4 |
B64_offset[*(srcp+i+2)]>>2);
*dstp++ = (B64_offset[*(srcp+i+2)]<<6 |
B64_offset[*(srcp+i+3)] );
i += 4;
}
srcp += i;

if(*(srcp-2) == '=')  /* remove 2 bytes of '='  padded while encoding */
{
*(dstp--) = '\0';
*(dstp--) = '\0';
}
else if(*(srcp-1) == '=') /* remove 1 byte of '='  padded while encoding */
*(dstp--) = '\0';

*dstp = '\0';

return dst;
};

size_t B64_length(size_t len)
{
// padded for multiple of 3 bytes
return  (size*8)/6;
}

size_t Ascii_length(size_t len)
{
return  (len*6)/8;
}

};```

## Using the Code

If you want to use the code in your project, just copy the code directly from this page and paste into your source file or copy Base64_RC4.h into your project folder and insert a header line.

`#include "Base64_RC4.h" `

#### A Demo of Using the Classes

```#include "Base64_RC4.h"
void main()
{
char str[64] = "This is a test for RC4 cypher";
/* Test rc4 encoding and decoding here */
CRC4 rc4;
printf("Demo for RC4 \n\n");
printf("Plain text: %s \n",str);
rc4.Encrypt(str,"Key");
printf("Encoded string: %s \n",str);
rc4.Decrypt(str,"Key");
printf("Decoded string: %s \n",str);
/* Test Base64  encoding and decoding here */
strcpy(str, "This is a test for Base64 cypher");
CBase64  base64;
char *dst;
dst = (char*)malloc( base64.B64_length(strlen(str))+1);
if(dst == NULL)
return;
printf("\n\nDemo for Base64 \n\n");
printf("Plain text: %s \n",str);
base64.Encrypt(str,strlen(str),dst);
printf("Encoded string: %s\n",dst);
memset(str,0,sizeof(str));
base64.Decrypt(dst,strlen(dst),str);
printf("Decoded string: %s\n",str);
free(dst);
getchar();
}```

## Points of Interest

Encoding/decoding is a lot of fun and critical for security, try to use it and feel its magic.

## Share

Jerry Jiang(BOLIANG JIANG)

A passionate software developer since 1992

Education:Master of Computer Science.

jerry@smarttick.com

## You may also be interested in...

 Pro Pro

 First Prev Next
 Your RC4 Decript function maybe incorrect. NullMiracle4-May-14 21:44 NullMiracle 4-May-14 21:44
 Swap Problem See_Sharp4-Sep-12 8:04 See_Sharp 4-Sep-12 8:04
 Re: Swap Problem Jerry Jiang17-Sep-12 20:07 Jerry Jiang 17-Sep-12 20:07
 Seems to mess up on a NULL Member 85519101-Jul-12 9:32 Member 8551910 1-Jul-12 9:32
 Re: Seems to mess up on a NULL Member 85519101-Jul-12 9:38 Member 8551910 1-Jul-12 9:38
 Re: Seems to mess up on a NULL Jerry Jiang17-Sep-12 20:19 Jerry Jiang 17-Sep-12 20:19
 Query on the key. Snehamoy Banerjee21-Aug-11 2:05 Snehamoy Banerjee 21-Aug-11 2:05
 Re: Query on the key. Jerry Jiang24-Sep-11 22:19 Jerry Jiang 24-Sep-11 22:19
 Hi Snehamoy, RC4 is a Symmetric-key algorithm which usually means the same key for both encryption of plaintext and decryption of ciphertext. If you want to randomly create password for the encryption, you may consider using a kind of asymmetric-key algorithm for encryption with which you can use a specific algorithm to randomly create a pair of private / public key for different plaintext. one to lock or encrypt the plaintext, and one to unlock or decrypt the cyphertext.
 New code snippet for char *Encrypt(char *pszText,const char *pszKey) in class CRC4 Jerry Jiang10-Jul-09 8:22 Jerry Jiang 10-Jul-09 8:22
 Re: needs a lot more. [modified] Jerry Jiang14-Apr-09 9:52 Jerry Jiang 14-Apr-09 9:52
 My vote of 2 Nick Kulikovsky13-Apr-09 14:41 Nick Kulikovsky 13-Apr-09 14:41
 Re: My vote of 2 [modified] Jerry Jiang13-Apr-09 16:50 Jerry Jiang 13-Apr-09 16:50
 Re: My vote of 2 yafan15-Apr-09 11:42 yafan 15-Apr-09 11:42
 Re: My vote of 2 [modified] Jerry Jiang15-Apr-09 17:05 Jerry Jiang 15-Apr-09 17:05
 My vote of 2 surajfrommumbai12-Apr-09 18:16 surajfrommumbai 12-Apr-09 18:16
 Re: My vote of 2 [modified] Jerry Jiang12-Apr-09 19:08 Jerry Jiang 12-Apr-09 19:08
 Last Visit: 31-Dec-99 18:00     Last Update: 25-Sep-16 21:14 Refresh 1