In this tip, you will see a simple Cipher Transform derived from ICryptoTransform based on a user defined CryptoBlock.
A Simple Cipher Derived from System.Security.Cryptography.ICryptoTransform
This is a simple cipher transform that is user defined.
Using the Code
This is how the abstract
class CryptoBlock
works. It is a Dictionary<byte, byte>
which is a user defined CryptoBlock
, this must have a block size of 256 and no key value pair can match.
using System.Collections.Generic;
namespace Chico.CipherCrypto>
{
public abstract class CryptoBlock : Dictionary<byte>,byte>
{
public const int BlockSize = 256;
protected CryptoBlock() : base(BlockSize)
{
}
}
}
Here, we will take a look at the CipherTransform
. This class is based on ICryptoTransform
and is used with a CryptoStream
.
using System;
using System.Linq;
using System.Diagnostics;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace Chico.CipherCrypto
{
[DebuggerStepThrough]
public class CipherTransform : ICryptoTransform
{
private CryptoBlock cipher;
public CipherTransform(CryptoBlock cryptoBlock)
{
var cipher = typeof(CryptoBlock);
if (cryptoBlock == null)
{
throw new NotImplementedException(cipher + " can not be null.");
}
if (cryptoBlock.Count != CryptoBlock.BlockSize)
{
throw new NotSupportedException(cipher + "is not supported");
}
byte[] keys = cryptoBlock.Keys.ToArray();
byte[] values = cryptoBlock.Values.ToArray();
for (int i = 0; i < keys.Length; i++)
{
if (keys[i] == values[i])
{
throw new NotSupportedException(cipher + " is not supported.");
}
}
this.cipher = cryptoBlock;
}
public void Dispose() => this.cipher.Clear();
bool ICryptoTransform.CanReuseTransform => true;
bool ICryptoTransform.CanTransformMultipleBlocks => true;
int ICryptoTransform.InputBlockSize => CryptoBlock.BlockSize;
int ICryptoTransform.OutputBlockSize => CryptoBlock.BlockSize;
private void Cipher(byte[] buffer, int offset, int count)
{
for (int i = offset; i < count; i++)
{
byte current = buffer[i];
byte next = this.cipher[current];
buffer[i] = next;
}
}
public int TransformBlock(byte[] inputBuffer, int inputOffset,
int inputCount, byte[] outputBuffer, int outputOffset)
{
Array.Copy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
Cipher(outputBuffer, outputOffset, inputCount);
return inputCount;
}
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
{
byte[] outputBuffer = new byte[inputCount];
Array.Copy(inputBuffer, inputOffset, outputBuffer, 0, inputCount);
Cipher(outputBuffer, 0, inputCount);
return outputBuffer;
}
}
}
History
- 16th February, 2022: Version 1