Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Decrypt RC4 values

Posted on 2012-12-24
1
Medium Priority
?
1,435 Views
Last Modified: 2013-01-10
I'm unable to decrypt RC4 encrypted querystring values from a .net web application.  I have the key and the encrypted text but I'm not able to get the original value.  The values are encoded before being sent in a querystring and I'm using URLDecode on the parameters before trying to decrypt.

When I attempt to decrypt, I get unreadable characters instead of the original text.  The data is being sent from a java application and I'm using an asp.net application to decrypt.

I'm using the attached sample code below to encrypt and decrypt data.  There is one function to encrypt and decrypt.

Does anyone know know how to get the original value from the encrypted text?  Could the encrypted text be in a different format?
using System;
using System.Text;
using Microsoft.VisualBasic;

namespace main
{
	public class rc4encrypt
	{
		protected int[] sbox = new int[256];
		protected int[] key = new int[256];

		protected string plaintext, password;

		public string PlainText
		{
			set { plaintext = value; }
			get { return plaintext; }
		}

		public string Password
		{
			set { password = value; }
			get { return password; }
		}

		private void RC4Initialize(string strPwd)
		{
			// Get the length of the password
			// Instead of Len(), we need to use the Length property
			// of the string
			int intLength = strPwd.Length;

			// Set up our for loop.  In C#, we need to change our syntax.

			// The first argument is the initializer.  Here we declare a
			// as an integer and set it equal to zero.

			// The second argument is expression that is used to test
			// for the loop termination.  Since our arrays have 256
			// elements and are always zero based, we need to loop as long
			// as a is less than or equal to 255.

			// The third argument is an iterator used to increment the
			// value of a by one each time through the loop.  Note that
			// we can use the ++ increment notation instead of a = a + 1
			for (int a = 0; a <= 255; a++)
			{
				// Since we don't have Mid()  in C#, we use the C#
				// equivalent of Mid(), String.Substring, to get a
				// single character from strPwd.  We declare a character
				// variable, ctmp, to hold this value.

				// A couple things to note.  First, the Mod keyword we
				// used in VB need to be replaced with the %
				// operator C# uses.  Next, since the return type of
				// String.Substring is a string, we need to convert it to
				// a char using String.ToCharArray() and specifying that
				// we want the first value in the array, [0].

				char ctmp = (strPwd.Substring((a % intLength),
					1).ToCharArray()[0]);

				// We now have our character and need to get the ASCII
				// code for it.  C# doesn't have the  VB Asc(), but that
				// doesn't mean we can't use it.  In the beginning of our
				// code, we imported the Microsoft.VisualBasic namespace.
				// This allows us to use many of the native VB functions
				// in C#
                
				// Note that we need to use [] instead of () for our
				// array members.
				key[a] = Microsoft.VisualBasic.Strings.Asc(ctmp);
				sbox[a] = a;
			}

			// Declare an integer x and initialize it to zero.
			int x = 0;

			// Again, create a for loop like the one above.  Note that we
			// need to use a different variable since we've already
			// declared a above.
			for (int b = 0; b <= 255; b++)
			{
				x = (x + sbox[b] + key[b]) % 256;
				int tempSwap = sbox[b];
				sbox[b] = sbox[x];
				sbox[x] = tempSwap;
			}
		}
		
		public string EnDeCrypt()
		{
			int i = 0;
			int j = 0;
			string cipher = "";

			// Call our method to initialize the arrays used here.
			RC4Initialize(password);

			// Set up a for loop.  Again, we use the Length property
			// of our String instead of the Len() function

			for (int a = 1; a <= plaintext.Length; a++)
			{
				// Initialize an integer variable we will use in this loop
				int itmp = 0;


				// Like the RC4Initialize method, we need to use the %
				// in place of Mod
				i = (i + 1) % 256;
				j = (j + sbox[i]) % 256;
				itmp = sbox[i];
				sbox[i] = sbox[j];
				sbox[j] = itmp;

				int k = sbox[(sbox[i] + sbox[j]) % 256];

				// Again, since the return type of String.Substring is a
				// string, we need to convert it to a char using
				// String.ToCharArray() and specifying that we want the
				// first value, [0].

				char ctmp = plaintext.Substring(a - 1, 1).ToCharArray()
					[0];

				// Use Asc() from the Microsoft.VisualBasic namespace
				itmp = Microsoft.VisualBasic.Strings.Asc(ctmp);

				// Here we need to use ^ operator that C# uses for Xor
				int cipherby = itmp ^ k;

				// Use Chr() from the Microsoft.VisualBasic namespace                
				cipher += Microsoft.VisualBasic.Strings.Chr(cipherby);
			}

			// Return the value of cipher as the return value of our
			// method
			return cipher;
		}

	}
}

Open in new window

RC4.txt
0
Comment
Question by:JeffDun
[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
1 Comment
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 2000 total points
ID: 38719383
There's a javascript version here: http://shop-js.sourceforge.net/crypto.htm 

The trick they use is base64 encoding after encryption because the 'string' you return from EnDeCrypt() does not by definition consist of printable characters. The downside is of course that decryption has to be done by first translating the base64 encoded string back to the original encrypted string.

I made a little test program with the key in textBox1 and the text in textBox2, encrypting would be done like this:
main.rc4encrypt rc4 = new main.rc4encrypt();
rc4.Password = textBox1.Text;
rc4.PlainText = textBox2.Text;
textBox2.Text = Convert.ToBase64String(enc.GetBytes(rc4.EnDeCrypt()));

Open in new window

and decryption:
main.rc4encrypt rc4 = new main.rc4encrypt();
rc4.Password = textBox1.Text;
rc4.PlainText = enc.GetString(Convert.FromBase64String(textBox2.Text));
textBox2.Text = rc4.EnDeCrypt();

Open in new window

where you could use for both for example:
Encoding enc = Encoding.Default;

Open in new window


EDIT: actually in keeping with your Chr/Asc usage you should probably use Encoding.ASCII
0

Featured Post

When ransomware hits your clients, what do you do?

MSPs: Endpoint security isn’t enough to prevent ransomware.
As the impact and severity of crypto ransomware attacks has grown, Webroot has fought back, not just by building a next-gen endpoint solution capable of preventing ransomware attacks but also by being a thought leader.

Question has a verified solution.

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

If you thought ransomware was bad, think again! Doxware has the potential to be even more damaging.
As a financial services provider, your business is impacted by two of the strictest federal regulations on record: the Sarbanes-Oxley Act and the Gramm-Leach-Bliley Act. Correctly implementing faxing into your organization to provide secure, real-ti…
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 …
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
Suggested Courses

715 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