JoeD77
asked on
RC4 Encryption crashing on attempt
hello
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!
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;
}
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!
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.
BTW, see also the exanple at http://en.wikipedia.org/wiki/RC4#Implementation
Replace the sizeof()'s with strlen in your main:
DWORD dwBufLen = strlen((const char *)lpBuf);
DWORD dwKeyLen = strlen((const char *)lpKey);
DWORD dwBufLen = strlen((const char *)lpBuf);
DWORD dwKeyLen = strlen((const char *)lpKey);
ASKER
@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:
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!
@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;
}
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!
ASKER
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!
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!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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...
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;
}