namespace com.hitrust.b2b.Security.Cryptography
|
|
{
|
|
using com.hitrust.b2b.Security;
|
|
using System;
|
|
using System.Security.Cryptography;
|
|
|
|
internal class RC4UnmanagedTransform : ICryptoTransform, IDisposable
|
|
{
|
|
private SymmetricKey m_Key;
|
|
|
|
public RC4UnmanagedTransform(byte[] key)
|
|
{
|
|
this.m_Key = new SymmetricKey(CryptoProvider.RsaFull, CryptoAlgorithm.RC4, key);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (this.m_Key != null)
|
|
{
|
|
this.m_Key.Dispose();
|
|
this.m_Key = null;
|
|
}
|
|
try
|
|
{
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
~RC4UnmanagedTransform()
|
|
{
|
|
this.Dispose();
|
|
}
|
|
|
|
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
|
|
{
|
|
if (this.m_Key == null)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
if ((inputBuffer == null) || (outputBuffer == null))
|
|
{
|
|
throw new ArgumentNullException();
|
|
}
|
|
if (((inputCount < 0) || (inputOffset < 0)) || (((outputOffset < 0) || ((inputOffset + inputCount) > inputBuffer.Length)) || ((outputBuffer.Length - outputOffset) < inputCount)))
|
|
{
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
byte[] destinationArray = new byte[inputCount];
|
|
int length = destinationArray.Length;
|
|
Array.Copy(inputBuffer, inputOffset, destinationArray, 0, length);
|
|
if (SspiProvider.CryptEncrypt(this.m_Key.Handle, 0, 0, 0, destinationArray, ref length, length) == 0)
|
|
{
|
|
throw new CryptographicException("Could not transform data.");
|
|
}
|
|
Array.Copy(destinationArray, 0, outputBuffer, outputOffset, length);
|
|
Array.Clear(destinationArray, 0, destinationArray.Length);
|
|
return length;
|
|
}
|
|
|
|
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
|
|
{
|
|
if (this.m_Key == null)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
if (inputBuffer == null)
|
|
{
|
|
throw new ArgumentNullException();
|
|
}
|
|
if (((inputCount < 0) || (inputOffset < 0)) || ((inputOffset + inputCount) > inputBuffer.Length))
|
|
{
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
byte[] destinationArray = new byte[inputCount];
|
|
int length = destinationArray.Length;
|
|
Array.Copy(inputBuffer, inputOffset, destinationArray, 0, length);
|
|
if (SspiProvider.CryptEncrypt(this.m_Key.Handle, 0, 1, 0, destinationArray, ref length, length) == 0)
|
|
{
|
|
throw new CryptographicException("Could not transform data.");
|
|
}
|
|
return destinationArray;
|
|
}
|
|
|
|
public bool CanReuseTransform
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public bool CanTransformMultipleBlocks
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public int InputBlockSize
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public int OutputBlockSize
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|