title: RC4 encryption not matching what's expected
body: <p>I'm having some problems using a bank's web service to pass in credit card payments. They require RC4 encryption on the outbound data, which they expect to be in a hexadecimal format.</p>
  
  <p>Here is the testing website they gave me to use: <a href="http://www.fyneworks.com/encryption/rc4-encryption/index.asp" rel="nofollow">http://www.fyneworks.com/encryption/rc4-encryption/index.asp</a></p>
  
  <p>When I take a sample card, and pass in the values generated by the form above,  they are correct, and the card is accepted. When I use my frankencode below (cobbled together from snippets I found on the internet), the hexadecimal values are just incorrect, and the card is declined every time. In some cases, encName, it is TOTALLY OFF. In the case of encCCNum and encCVVTest, it is about half-right. In the case of encExpyMonth and encExpyYear, its COMPLETELY RIGHT.</p>
  
  <p>I'm sure the issue is in my algorithm somewhere, or maybe even the hexadecimal conversion, but I'm really not too experienced in cryptography programming, so I don't even know where to begin debugging. Can someone please help me? This is a web application in C#.net, btw.</p>
  
  <pre><code> rc4encrypt rc4 = new rc4encrypt();
   rc4.Password = "B83E13EC";
   rc4.PlainText = sNameTest;
   encName = rc4.EnDeCrypt();
   rc4.Password = "B83E13EC";
   rc4.PlainText = sCCNumTest;
   encCCNum = rc4.EnDeCrypt();
   rc4.Password = "B83E13EC";
   rc4.PlainText = sExpyMonthTest;
   encExpyMonth = rc4.EnDeCrypt();
   rc4.Password = "B83E13EC";
   rc4.PlainText = sExpyYearTest;
   encExpyYear = rc4.EnDeCrypt();
   rc4.Password = "B83E13EC";
   rc4.PlainText = sCVVTest;
   encCVVTest = rc4.EnDeCrypt();
  
     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 &lt;= 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 &lt;= 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 &lt;= 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
  
              //Convert to hexadecimal - added by BN
              string finalcipher = string.Empty;
              char[] values = cipher.ToCharArray();
              foreach (char letter in values)
              {
                  // Get the integral value of the character. 
                  int value = Convert.ToInt32(letter);
                  // Convert the decimal value to a hexadecimal value in string form. 
                  finalcipher += String.Format("{0:X}", value);
  
              }
  
              return finalcipher;
          }
  
      }
  </code></pre>