?
Solved

RC4 Encryption crashing on attempt

Posted on 2011-02-12
7
Medium Priority
?
419 Views
Last Modified: 2012-05-11
hello
unsigned char* RC4(unsigned char* lpBuf, unsigned char* lpKey, DWORD dwBufLen, DWORD dwKeyLen)
{
	int a, c = 0, s[256];
	BYTE swap;
	DWORD dwCount;
	for(a = 0; a < 256; a++)
	{
		s[a] = a;
	}
	for(a = 0; a < 256; a++)
	{
		c = (c + s[a] + lpKey[a % dwKeyLen]) % 256;
		swap = s[a];
		s[a] = s[c];
		s[c] = swap;
	}
	for(dwCount = 0; dwCount < dwBufLen; dwCount++)
	{
		a = (a + 1) % 256;
		c = (c + s[a]) % 256;
		swap = s[a];
		s[a] = s[c];
		s[c] = swap;
		lpBuf[dwCount] ^= s[(s[a] + s[c]) % 256];
	}
	return lpBuf;
}


int main()
{
	unsigned char* lpBuf = (unsigned char*)"text to encrypt";
	unsigned char* lpKey = (unsigned char*)"mykey123";
	DWORD dwBufLen = sizeof(lpBuf);
	DWORD dwKeyLen = sizeof(lpKey);
	unsigned char* result = RC4(&lpBuf[0], &lpKey[0], dwBufLen, dwKeyLen);
	cout  << result;
	return 0;
}

Open in new window


that's my code.

it crashes when it reaches the line:
"lpBuf[dwCount] ^= s[(s[a] + s[c]) % 256];"
and it returns back an Access Violation when I debug

Does anyone see what I'm doing wrong?

Thank you
Thank you!
0
Comment
Question by:JoeD77
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 34880054
That is because when the crash occurs, 's[a] == 49' and 's[c] == 231' - since the array is 's[256]', the resulting access to 's[280]' is clearly out of bounds of that array.
0
 
LVL 86

Expert Comment

by:jkr
ID: 34880063
0
 
LVL 9

Expert Comment

by:AriMc
ID: 34880076
Replace the sizeof()'s with strlen in your main:

      DWORD dwBufLen = strlen((const char *)lpBuf);
      DWORD dwKeyLen = strlen((const char *)lpKey);
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:JoeD77
ID: 34880199
@jkr: I changed the size of the array to 280 for debugging purposes and still it crashes. That wikipedia implementation is confusing to me based on what I'm trying to achieve

@AriMc: Thanks for pointing that out, I changed that code and still it crashes

I've been looking around and I came across another nice rc4 implementation:
void swapints(int *array, int ndx1, int ndx2)
{
    int temp = array[ndx1];
    array[ndx1] = array[ndx2];
    array[ndx2] = temp;
}

char *EnDeCrypt(const char *pszText, int iTextLen, const char *pszKey)

{
    char *cipher;                       
    int a, b, i=0, j=0, k;              
    int ilen;                           
    int sbox[256];                      
    int key[256];                       

    ilen = strlen(pszKey);

    for (a=0; a < 256; a++)
    {
        key[a] = pszKey[a % ilen];
        sbox[a] = a;
    }

    for (a=0, b=0; a < 256; a++)
    {
        b = (b + sbox[a] + key[a]) % 256;
        swapints(sbox, a, b);
    }

    cipher = (char *)malloc(iTextLen);

    for (a=0; a < iTextLen; a++)
    {
        i = (i + 1) % 256;
        j = (j + sbox[i]) % 256;
        swapints(sbox, i, j);
        k = sbox[(sbox[i] + sbox[j]) % 256];
        cipher[a] = pszText[a] ^ k;
    }
    return cipher;
}


int main()
{
	const char* lpBuf = (const char*)"texttoencrypt";
	const char* lpKey = (const char*)"mykey123";
	DWORD dwBufLen = sizeof(lpBuf);
	DWORD dwKeyLen = sizeof(lpKey);
    char* result = EnDeCrypt(lpBuf, dwBufLen, lpKey);
	char* resultdec = EnDeCrypt((const char*)result, sizeof(result), lpKey);
	cout  << "Encrypted Data:\n" << result;
	cout << "\n\n\nDecrypted Data:\n" << resultdec << "\n";
	return 0;
}

Open in new window


It's still not working properly. It outputs:
"Encrypted Data:
+ɦ+²²²²1


Decrypted Data:
text²²²²1"

it seems like it encrypts/decrypts correctly up until the fourth byte is reached... then something happens.

Any help would be appreciated

thanks!
0
 

Author Comment

by:JoeD77
ID: 34880216
Ah, it was only outputting the first 4 because the size was being miscalculated, but I changed the code to:
DWORD dwBufLen = strlen((const char *)lpBuf);
DWORD dwKeyLen = strlen((const char *)lpKey);
(thanks again for pointing that out)

now it outputs:
Encrypted Data:
+ɦ+;~0¿¬¡¶¬°²²²²


Decrypted Data:
texttoencrypt+vöO²²²²

why is it outputting that gibrish on the end along with the encrypted/decrypted strings? is there any way I can prevent that?

Thanks!
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 34880311
Yes - either add a NULL terminator or include that by using

DWORD dwBufLen = strlen((const char *)lpBuf) + 1;

or explicitly use the size of that data as a width delimiter with 'cout', e.g.


#include <iomanip>

//...

	cout<< setw(dwBufLen) << "\n\n\nDecrypted Data:\n" << resultdec << "\n";

Open in new window

0
 
LVL 8

Expert Comment

by:lomo74
ID: 34883185
what about this --
pay attention anyway, encoded data may contain zeroes.
you cannot treat it as a string, since a zero is *not* necessarily the end of the encoded string.
cout << encoded;   is somewhat dangerous... only good for testing...


void RC4(const unsigned char *lpIn,
	unsigned char *lpOut,
	const unsigned char *lpKey,
	unsigned int bufLen,
	unsigned int keyLen)
{
	int i, j = 0, s[256];
	unsigned int l;
	unsigned char temp;

	for (i = 0; i < 256; i++)
		s[i] = i;

	for (i = 0; i < 256; i++)
	{
		j = (j + s[i] + lpKey[i % keyLen]) % 256;
		temp = s[i];
		s[i] = s[j];
		s[j] = temp;
	}

	i = 0;
	j = 0;
	for (l = 0; l < bufLen; l++)
	{
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		temp = s[i];
		s[i] = s[j];
		s[j] = temp;
		lpOut[l] = lpIn[l] ^ s[(s[i] + s[j]) % 256];
	}
}

int main(int argc, char* argv[])
{
	unsigned char* lpBuf = (unsigned char*)"text to encrypt";
	unsigned char* lpKey = (unsigned char*)"mykey123";
	DWORD dwBufLen = strlen(lpBuf);
	DWORD dwKeyLen = strlen(lpKey);
	unsigned char* lpOut = (unsigned char*)malloc(dwBufLen);
	//encode
	RC4(lpBuf, lpOut, lpKey, dwBufLen, dwKeyLen);
	cout  << lpOut << endl;
	//decode back
	RC4(lpOut, lpOut, lpKey, dwBufLen, dwKeyLen);
	cout  << lpOut << endl;
	free(lpOut);
	return 0;
}

Open in new window

0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Envision that you are chipping away at another e-business site with a team of pundit developers and designers. Everything seems, by all accounts, to be going easily.
Ransomware is a growing menace to anyone using a computer or mobile device. Here are answers to some common questions about this vicious new form of malware.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question