[转载]如何使用RC4进行数据加减密

如何使用RC4进行数据加减密
如何使用RC4进行数据加减密

最近帮一个网友解决RC4加减密的问题,虽说在网上有类似的问题,但是对于中文解决不是很理想,因此我在别人的基础上进行修改,并且为了方便显示,把加密后的字符串用16进制来显示。

大致的代码如下:

//-------------------------- RC4 encrypt class ------------------------------------

//---------------------------------------------------------------------------------

//---File: clsRC4Engine

//---Description: The encrypt class file using RC4

//---Author: Knight

//---Date: Jul.3, 2006

//---------------------------------------------------------------------------------

//--------------------------{RC4 encrypt class}-------------------------------------

namespace CryptoRC4

{

using System;

using System.Text;

///

/// Summary description for clsRC4Engine.

///

public class clsRC4Engine

{

private static long m_nBoxLen = 255;

///

/// Avoid this class to be inited

///

protected clsRC4Engine()

{

//

// TODO: Add constructor logic here

//

}

private static void GetKeyBytes( string Key, out byte[] m_nBox )

{

//

// Used to populate m_nBox

//

long index2 = 0;

m_nBox = new byte[m_nBoxLen];

//

// Create two different encoding

//

Encoding ascii = Encoding.ASCII;

Encoding unicode = Encoding.Unicode;

//

// Perform the conversion of the encryption key from unicode to ansi

//

byte[] asciiBytes = Encoding.Convert(unicode,ascii,

unicode.GetBytes( Key ));

//

// Convert the new byte[] into a char[] and then to string

//

char[] asciiChars = new char[ascii.GetCharCount(asciiBytes,0,asciiBytes.Length)];

ascii.GetChars(asciiBytes,0,asciiBytes.Length,asciiChars,0);

//this.m_sEncryptionKeyAscii = new string(asciiChars);

//

// Populate m_nBox

//

long KeyLen = Key.Length;

//

// First Loop

//

for ( long count = 0; count < m_nBoxLen ; count ++ )

{

m_nBox[count] = (byte)count;

}

//

// Second Loop

//

for ( long count = 0; count < m_nBoxLen ; count ++ )

{

index2 = (index2 + m_nBox[count] + asciiChars[ count % KeyLen ]) % m_nBoxLen;

byte temp = m_nBox[count];

m_nBox[count] = m_nBox[index2];

m_nBox[index2] = temp;

}

}

///

/// Get encrypted bytes

///

///

///

///

///

private static bool GetEncryptBytes( string sData, byte[] m_nBox,

out byte[] EncryptedBytes )

{

EncryptedBytes = null;

bool toRet = true;

try

{

//

// indexes used below

//

long i=0;

long j=0;

//

// Put input string in temporary byte array

//

Encoding enc_default = Encoding.Unicode;

byte[] input = enc_default.GetBytes( sData );

//

// Output byte array

//

EncryptedBytes = new byte[input.Length];

//

// Local copy of m_nBoxLen

//

byte[] n_LocBox = new byte[m_nBoxLen];

m_nBox.CopyTo(n_LocBox,0);

//

// Len of Chipher

//

long ChipherLen = input.Length + 1;

//

// Run Alghoritm

//

for ( long offset = 0; offset < input.Length ; offset++ )

{

i = ( i + 1 ) % m_nBoxLen;

j = ( j + n_LocBox[i] ) % m_nBoxLen;

byte temp = n_LocBox[i];

n_LocBox[i] = n_LocBox[j];

n_LocBox[j] = temp;

byte a = input[offset];

byte b = n_LocBox[(n_LocBox[i]+n_LocBox[j])% m_nBoxLen];

EncryptedBytes[offset] = (byte)((int)a^(int)b);

}

}

catch

{

EncryptedBytes = null;

//

// error occured - set retcode to false.

//

toRet = false;

}

return toRet;

}

///

/// Encrypt data through specific key value

///

///

///

///

///

public static bool Encrypt( string sData, string Key, out string EncryptedString )

{

EncryptedString = null;

if( sData == null || Key == null ) return false;

byte[] m_nBox;

GetKeyBytes( Key, out m_nBox );

byte[] output;

if( GetEncryptBytes( sData, m_nBox, out output ) )

{

// Convert data to hex-data

EncryptedString = "";

for( int i = 0; i < output.Length; i++ )

EncryptedString += output[i].ToString( "X2" );

return true;

}

else

return false;

}

///

/// Decrypt data using specific key

///

///

///

///

///

public static bool Decrypt( string EncryptedString, string Key, out string sData )

{

sData = null;

if( EncryptedString == null || Key == null ) return false;

else if( EncryptedString.Length % 2 != 0 ) return false;

byte[] m_nBox;

GetKeyBytes( Key, out m_nBox );

// Convert data from hex-data to string

byte[] bData = new byte[EncryptedString.Length / 2];

for( int i = 0; i < bData.Length; i++ )

bData[i] = Convert.ToByte( EncryptedString.Substring( i * 2, 2 ), 16 );

EncryptedString = Encoding.Unicode.GetString( bData );

byte[] output;

if( GetEncryptBytes( EncryptedString, m_nBox, out output ) )

{

sData = Encoding.Unicode.GetString( output );

return true;

}

else

return false;

}

}

}

调用如下:

//Encrypt data

string strEncryptedString;

if( clsRC4Engine.Encrypt( strValue, strKey, out strEncryptedString ) )

MessageBox.Show( strEncryptedString );

//Decrypt data

string strDecryptedString;

if( clsRC4Engine.Decrypt( strValue, strKey, out strDecryptedString ) )

MessageBox.Show( strDecryptedString );

请使用浏览器的分享功能分享到微信等