RC4 Encryption in C#

The RC4 algorithm is a symmetric stream cipher and despite having known security vulnerabilities, RC4 is still widely used. I'm quite fond of RC4 due to the ease of implementation which made RC4 an ideal choice of symmetric encryption algorithm back in the good old days of Classic ASP. This algorithm is purely for interest as the .NET framework has better symmetric encryption algorithms that I recommend you use over RC4.

Here is a C# implementation of RC4 with some added LINQ goodness. This RC4 implementation will encrypt/decrypt strings and byte arrays.

The code for this C# version of RC4 can be downloaded from the link at the bottom of this post.

public static class RC4
{
   public static string Encrypt(string key, string data)
   {
      Encoding unicode = Encoding.Unicode;

      return Convert.ToBase64String(Encrypt(unicode.GetBytes(key), unicode.GetBytes(data)));
   }

   public static string Decrypt(string key, string data)
   {
      Encoding unicode = Encoding.Unicode;

      return unicode.GetString(Encrypt(unicode.GetBytes(key), Convert.FromBase64String(data)));
   }

   public static byte[] Encrypt(byte[] key, byte[] data)
   {
      return EncryptOutput(key, data).ToArray();
   }

   public static byte[] Decrypt(byte[] key, byte[] data)
   {
      return EncryptOutput(key, data).ToArray();
   }

   private static byte[] EncryptInitalize(byte[] key)
   {
      byte[] s = Enumerable.Range(0, 256)
        .Select(i => (byte)i)
        .ToArray();

      for (int i = 0, j = 0; i < 256; i++)
      {
         j = (j + key[i % key.Length] + s[i]) & 255;

         Swap(s, i, j);
      }

      return s;
   }

   private static IEnumerable<byte> EncryptOutput(byte[] key, IEnumerable<byte> data)
   {
      byte[] s = EncryptInitalize(key);

      int i = 0;
      int j = 0;

      return data.Select((b) =>
      {
         i = (i + 1) & 255;
         j = (j + s[i]) & 255;

         Swap(s, i, j);

         return (byte)(b ^ s[(s[i] + s[j]) & 255]);
      });
   }

   private static void Swap(byte[] s, int i, int j)
   {
      byte c = s[i];

      s[i] = s[j];
      s[j] = c;
   }
}