Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / security / cryptography

A Basic Cipher Transform

1.00/5 (1 vote)
16 Feb 2022CPOL 5.6K   45  
Simple user defined Cipher Transform that I got the idea from https://www.codeproject.com/Articles/5319044/ARC4-Encryption-Library
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.

C#
// This is the base CryptoBlock used for the CipherTransform class
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.

C#
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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)