Search code examples
c#encryptionencryption-symmetric

Symmetric encryption algorithm function


To start off, I am still learning object oriented programming. Ok, I have a combo box with the different types of symmetric algorithms.

private void Form3_Load(object sender, EventArgs e)
{
    openencrypt();
    comboBox1.Items.Add("AES");
    comboBox1.Items.Add("DES");
    comboBox1.Items.Add("Rijndael");
    comboBox1.Items.Add("RC2");
    comboBox1.Items.Add("Triple DES");
    comboBox1.SelectedIndex = 0;
}

Then I have my encrypt function checking what types they are.

byte[] hpass;
string nFilepath = Set.nfilepath;
FileStream Open = new FileStream(oFilepath, FileMode.Open, FileAccess.Read);
FileStream Save = new FileStream(nFilepath, FileMode.OpenOrCreate, FileAccess.Write);
SHA512 sh512 = new SHA512Managed();
hpass = sh512.ComputeHash(Encoding.ASCII.GetBytes(textBox1.Text));
PasswordDeriveBytes pdb = new PasswordDeriveBytes(hpass, hash);

if (comboBox1.SelectedIndex.Equals(0))
{
    Aes alg = Aes.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
}
if (comboBox1.SelectedIndex.Equals(1))
{
    DES alg = DES.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
}
if (comboBox1.SelectedIndex.Equals(2))
{
    Rijndael alg = Rijndael.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
}

But when I don't want to have to put a crypto stream in each if statement. So is there a way to offload the checking to a function and return a symmetricalgorithm type? With the Key and IV? Am I going about this completely wrong?## Heading ##


Solution

  • A more object oriented approach would be:

    Create an algorithm interface to be displayed in your combo box:

    public interface IAlgorithmItem
    {
        SymmetricAlgorithm CreateAlgorithm();
    
        string DisplayName { get; }
    }
    

    Then, create a new class for each desired algorithm:

    public class AesAlgorithm : IAlgorithmItem
    {
        public AesAlgorithm()
        {
        }
    
        public SymmetricAlgorithm CreateAlgorithm()
        {
            return Aes.Create();
        }
    
        public string DisplayName
        {
            get { return "AES"; }
        }
    }
    
    public class RijndaelAlgorithm : IAlgorithmItem
    {
        public SymmetricAlgorithm CreateAlgorithm()
        {
            return Rijndael.Create(); 
        }
    
        public string DisplayName
        {
            get { return "Rijndael"; }
        }
    }
    
    // ...
    

    Then, you can create a new list of items:

    var listItems = new List<IAlgorithmItem>() { new AesAlgorithm(), new RijndaelAlgorithm() };
    

    Then you can bind your combo box to this list:

    comboBox1.DataSource = listItems;
    comboBox1.DisplayMember = "DisplayName";
    

    Later, you can reference the selected item:

    var algorithmItem = (IAlgorithmItem)comboBox1.SelectedItem;
    var algorithm = algorithmItem.CreateAlgorithm();
    

    EDIT: Updated with Will's suggestion of using an interface rather than an abstract base class. EDIT 2: Updated to use a create method rather than property, as the result of the operation will create a new algorithm each time it is accessed.