Click here to Skip to main content
15,884,176 members
Articles / Security / Cryptography
Tip/Trick

A Basic Cipher Transform

Rate me:
Please Sign up or sign in to vote.
1.00/5 (1 vote)
16 Feb 2022CPOL 5.2K   44   4   1
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)


Written By
United States United States
I do not claim to be wrong! I just rarely ever write.

Comments and Discussions

 
QuestionMyCryptoBlock Pin
charles henington16-Feb-22 11:35
charles henington16-Feb-22 11:35 
class MyCryptoBlock : CryptoBlock
    {        
        public MyCryptoBlock()
        {
            for (int i = 0; i < CryptoBlock.BlockSize; i++)
            {
                byte key = (byte)i;
                byte value = (byte)((CryptoBlock.BlockSize - 1) - key);
                this.Add(key, value);
            }
        }
    }

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.