namespace com.hitrust.b2b.Security.Cryptography { using System; using System.Security.Cryptography; internal sealed class ARCFourManagedTransform : ICryptoTransform, IDisposable { private bool m_Disposed; private byte m_Index1; private byte m_Index2; private byte[] m_Key; private int m_KeyLen; private byte[] m_Permutation; public ARCFourManagedTransform(byte[] key) { this.m_Key = (byte[]) key.Clone(); this.m_KeyLen = key.Length; this.m_Permutation = new byte[0x100]; this.m_Disposed = false; this.Init(); } public void Dispose() { Array.Clear(this.m_Key, 0, this.m_Key.Length); Array.Clear(this.m_Permutation, 0, this.m_Permutation.Length); this.m_Index1 = 0; this.m_Index2 = 0; this.m_Disposed = true; try { GC.SuppressFinalize(this); } catch { } } ~ARCFourManagedTransform() { this.Dispose(); } private void Init() { for (int i = 0; i < 0x100; i++) { this.m_Permutation[i] = (byte) i; } this.m_Index1 = 0; this.m_Index2 = 0; int index = 0; for (int j = 0; j < 0x100; j++) { index = ((index + this.m_Permutation[j]) + this.m_Key[j % this.m_KeyLen]) % 0x100; byte num = this.m_Permutation[j]; this.m_Permutation[j] = this.m_Permutation[index]; this.m_Permutation[index] = num; } } public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { if (this.m_Disposed) { throw new ObjectDisposedException(base.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(); } int num3 = inputOffset + inputCount; while (inputOffset < num3) { this.m_Index1 = (byte) ((this.m_Index1 + 1) % 0x100); this.m_Index2 = (byte) ((this.m_Index2 + this.m_Permutation[this.m_Index1]) % 0x100); byte num2 = this.m_Permutation[this.m_Index1]; this.m_Permutation[this.m_Index1] = this.m_Permutation[this.m_Index2]; this.m_Permutation[this.m_Index2] = num2; byte index = (byte) ((this.m_Permutation[this.m_Index1] + this.m_Permutation[this.m_Index2]) % 0x100); outputBuffer[outputOffset] = (byte) (inputBuffer[inputOffset] ^ this.m_Permutation[index]); inputOffset++; outputOffset++; } return inputCount; } public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { if (this.m_Disposed) { throw new ObjectDisposedException(base.GetType().FullName); } byte[] outputBuffer = new byte[inputCount]; this.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, 0); this.Init(); return outputBuffer; } public bool CanReuseTransform { get { return true; } } public bool CanTransformMultipleBlocks { get { return true; } } public int InputBlockSize { get { return 1; } } public int OutputBlockSize { get { return 1; } } } }