代码语言:javascript复制
public class RC4Cryptor
{
public byte[] Encrypt(byte[] data, string pwd)
{
SymmetricAlgorithm sa = RC4Creator.Create(); ;
//
byte[] inputByteArray = data;//得到需要加密的字节数组
//设置密钥及密钥向量
sa.Key = Encoding.UTF8.GetBytes(pwd);
sa.IV = null;
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, sa.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
byte[] cipherBytes = ms.ToArray();//得到加密后的字节数组
cs.Close();
ms.Close();
return cipherBytes;
}
public byte[] Decrypt(byte[] data, string pwd)
{
SymmetricAlgorithm sa = RC4Creator.Create();
//BLL.RC4.Create();
byte[] inputByteArray = data;//得到需要加密的字节数组
//设置密钥及密钥向量
sa.Key = Encoding.UTF8.GetBytes(pwd);
sa.IV = null;
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, sa.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
byte[] textBytes = ms.ToArray();//得到加密后的字节数组
cs.Close();
ms.Close();
return textBytes;
}
}
public class RC4 : SymmetricAlgorithm
{
/// <summary>
/// Initializes a new instance of the RC4 class.
/// </summary>
/// <remarks>
/// The default keysize is 128 bits.
/// </remarks>
public RC4()
{
this.KeySizeValue = 128;
}
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
{
throw new NotImplementedException();
}
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets or sets the block size of the cryptographic operation in bits.
/// </summary>
/// <value>The block size of RC4 is always 8 bits.</value>
/// <exception cref="CryptographicException">The block size is invalid.</exception>
public override int BlockSize
{
get
{
return 8;
}
set
{
if (value != 8 && value != 0)
throw new CryptographicException("RC4 is a stream cipher, not a block cipher.");
}
}
/// <summary>
/// Gets or sets the feedback size of the cryptographic operation in bits.
/// </summary>
/// <value>This property always throws a <see cref="CryptographicException"/>.</value>
/// <exception cref="CryptographicException">This exception is always thrown.</exception>
/// <remarks>RC4 doesn't use the FeedbackSize property.</remarks>
public override int FeedbackSize
{
get
{
throw new CryptographicException("RC4 doesn't use the feedback size property.");
}
set
{
throw new CryptographicException("RC4 doesn't use the feedback size property.");
}
}
/// <summary>
/// Gets or sets the initialization vector (IV) for the symmetric algorithm.
/// </summary>
/// <value>This property always returns a byte array of length one. The value of the byte in the array is always set to zero.</value>
/// <exception cref="CryptographicException">An attempt is made to set the IV to an invalid instance.</exception>
/// <remarks>RC4 doesn't use the IV property, however the property accepts IV's of up to one byte (RC4's <see cref="BlockSize"/>) in order to interoperate with software that has been written with the use of block ciphers in mind.</remarks>
public override byte[] IV
{
get
{
return new byte[1];
}
set
{
if (value != null && value.Length > 1)
throw new CryptographicException("RC4 doesn't use an Initialization Vector.");
}
}
/// <summary>
/// Gets the block sizes that are supported by the symmetric algorithm.
/// </summary>
/// <value>An array containing the block sizes supported by the algorithm.</value>
/// <remarks>Only a block size of one byte is supported by the RC4 algorithm.</remarks>
public override KeySizes[] LegalBlockSizes
{
get
{
return new KeySizes[] { new KeySizes(8, 8, 0) };
}
}
/// <summary>
/// Gets the key sizes that are supported by the symmetric algorithm.
/// </summary>
/// <value>An array containing the key sizes supported by the algorithm.</value>
/// <remarks>Only key sizes that match an entry in this array are supported by the symmetric algorithm.</remarks>
public override KeySizes[] LegalKeySizes
{
get
{
return new KeySizes[] { new KeySizes(8, 2048, 8) };
}
}
/// <summary>
/// Gets or sets the mode for operation of the symmetric algorithm.
/// </summary>
/// <value>The mode for operation of the symmetric algorithm.</value>
/// <remarks>RC4 only supports the OFB cipher mode. See <see cref="CipherMode"/> for a description of this mode.</remarks>
/// <exception cref="CryptographicException">The cipher mode is not OFB.</exception>
public override CipherMode Mode
{
get
{
return CipherMode.OFB;
}
set
{
if (value != CipherMode.OFB)
throw new CryptographicException("RC4 only supports OFB.");
}
}
/// <summary>
/// Gets or sets the padding mode used in the symmetric algorithm.
/// </summary>
/// <value>The padding mode used in the symmetric algorithm. This property always returns PaddingMode.None.</value>
/// <exception cref="CryptographicException">The padding mode is set to a padding mode other than PaddingMode.None.</exception>
public override PaddingMode Padding
{
get
{
return PaddingMode.None;
}
set
{
if (value != PaddingMode.None)
throw new CryptographicException("RC4 is a stream cipher, not a block cipher.");
}
}
/// <summary>
/// This is a stub method.
/// </summary>
/// <remarks>Since the RC4 cipher doesn't use an Initialization Vector, this method will not do anything.</remarks>
public override void GenerateIV()
{
// do nothing
}
/// <summary>
/// Generates a random Key to be used for the algorithm.
/// </summary>
/// <remarks>Use this method to generate a random key when none is specified.</remarks>
public override void GenerateKey()
{
byte[] key = new byte[this.KeySize / 8];
GetRNGCSP().GetBytes(key);
this.Key = key;
}
/// <summary>
/// Creates an instance of the default cryptographic object used to perform the RC4 transformation.
/// </summary>
/// <returns>The instance of a cryptographic object used to perform the RC4 transformation.</returns>
public static new RC4 Create()
{
return Create("ARCFOUR");
}
/// <summary>
/// Creates an instance of the specified cryptographic object used to perform the RC4 transformation.
/// </summary>
/// <param name="AlgName">The name of the specific implementation of <see cref="RC4"/> to create.</param>
/// <returns>A cryptographic object.</returns>
public static new RC4 Create(string AlgName)
{
try
{
//if (AlgName.ToUpper() == "RC4" || AlgName.ToLower() == "org.mentalis.security.cryptography.rc4cryptoserviceprovider")
// return new RC4CryptoServiceProvider();
//else if (AlgName.ToUpper() == "ARCFOUR" || AlgName.ToLower() == "org.mentalis.security.cryptography.arcfourmanaged")
// return new ARCFourManaged();
return new RC4Creator();
}
catch { }
return null;
}
/// <summary>
/// Returns an <see cref="RNGCryptoServiceProvider"/> instance.
/// </summary>
/// <returns>An RNGCryptoServiceProvider instance.</returns>
protected RNGCryptoServiceProvider GetRNGCSP()
{
if (m_RNG == null)
m_RNG = new RNGCryptoServiceProvider();
return m_RNG;
}
/// <summary>
/// Holds the RNGCryptoServiceProvider object.
/// </summary>
private RNGCryptoServiceProvider m_RNG;
}
public class RC4Creator : RC4
{
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
{
if (m_IsDisposed)
throw new ObjectDisposedException(this.GetType().FullName);
if (rgbKey == null)
throw new ArgumentNullException("Key is a null reference.");
if (rgbKey.Length == 0 || rgbKey.Length > 256)
throw new CryptographicException("Invalid Key.");
if (rgbIV != null && rgbIV.Length > 1)
throw new CryptographicException("Invalid Initialization Vector.");
return new RC4CryptTransForm(rgbKey);
}
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
{
return CreateDecryptor(rgbKey, rgbIV); ;
}
public override void GenerateIV()
{
//do nothing;
}
public override void GenerateKey()
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(true);
m_IsDisposed = true;
}
private bool m_IsDisposed;
}
public class RC4CryptTransForm : ICryptoTransform
{
byte[] m_Key;
int m_KeyLen;
byte[] m_Permutation;
bool m_Disposed;
byte m_Index1;
byte m_Index2;
public RC4CryptTransForm(byte[] key)
{
m_Key = (byte[])key.Clone();
m_KeyLen = key.Length;
m_Permutation = new byte[256];
m_Disposed = false;
Init();
}
private void Init()
{
byte temp;
// init state variable
for (int i = 0; i < 256; i )
{
m_Permutation[i] = (byte)i;
}
m_Index1 = 0;
m_Index2 = 0;
// randomize, using key
for (int j = 0, i = 0; i < 256; i )
{
j = (j m_Permutation[i] m_Key[i % m_KeyLen]) % 256;
// swap m_State.permutation[i] and m_State.permutation[j]
temp = m_Permutation[i];
m_Permutation[i] = m_Permutation[j];
m_Permutation[j] = temp;
}
}
public bool CanReuseTransform
{
get { return true; }
}
public bool CanTransformMultipleBlocks
{
get { return true; }
}
public int InputBlockSize
{
get { return 1; }
}
public int OutputBlockSize
{
get { return 1; }
}
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
if (m_Disposed)
throw new ObjectDisposedException(this.GetType().FullName);
if (inputBuffer == null || outputBuffer == null)
throw new ArgumentNullException();
if (inputOffset < 0 || outputOffset < 0 || inputOffset inputCount > inputBuffer.Length || outputOffset inputCount > outputBuffer.Length)
throw new ArgumentOutOfRangeException();
byte j, temp;
int length = inputOffset inputCount;
for (; inputOffset < length; inputOffset , outputOffset )
{
// update indices
m_Index1 = (byte)((m_Index1 1) % 256);
m_Index2 = (byte)((m_Index2 m_Permutation[m_Index1]) % 256);
// swap m_State.permutation[m_State.index1] and m_State.permutation[m_State.index2]
temp = m_Permutation[m_Index1];
m_Permutation[m_Index1] = m_Permutation[m_Index2];
m_Permutation[m_Index2] = temp;
// transform byte
j = (byte)((m_Permutation[m_Index1] m_Permutation[m_Index2]) % 256);
outputBuffer[outputOffset] = (byte)(inputBuffer[inputOffset] ^ m_Permutation[j]);
}
return inputCount;
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
{
if (m_Disposed)
throw new ObjectDisposedException(this.GetType().FullName);
byte[] ret = new byte[inputCount];
TransformBlock(inputBuffer, inputOffset, inputCount, ret, 0);
Init();
return ret;
}
public void Dispose()
{
Array.Clear(m_Key, 0, m_Key.Length);
Array.Clear(m_Permutation, 0, m_Permutation.Length);
m_Index1 = 0;
m_Index2 = 0;
m_Disposed = true;
try
{
GC.SuppressFinalize(this);
}
catch { }
}
}