对称加密算法函数

4

首先,我仍在学习面向对象编程。好的,我有一个组合框,其中包含不同类型的对称算法。

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;
}

接着,我会让我的加密函数检查它们的类型。

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);
}

但是当我不想在每个if语句中都放入一个加密流时,是否有一种方法可以将检查卸载到一个函数中并返回对称算法类型?带有Key和IV?我的做法完全错误吗?##标题##

2个回答

2

更加面向对象的方法是:

创建一个算法接口,以在您的组合框中显示:

public interface IAlgorithmItem
{
    SymmetricAlgorithm CreateAlgorithm();

    string DisplayName { get; }
}

然后,为每个期望的算法创建一个新类:
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"; }
    }
}

// ...

然后,你可以创建一个新的项目列表:
var listItems = new List<IAlgorithmItem>() { new AesAlgorithm(), new RijndaelAlgorithm() };

然后,您可以将下拉框绑定到此列表:
comboBox1.DataSource = listItems;
comboBox1.DisplayMember = "DisplayName";

稍后,您可以引用所选项目:
var algorithmItem = (IAlgorithmItem)comboBox1.SelectedItem;
var algorithm = algorithmItem.CreateAlgorithm();

编辑:根据威尔的建议,使用接口而不是抽象基类。
编辑2:更新为使用create方法而非属性,因为每次访问操作的结果将创建一个新算法。


你应该使用接口而不是抽象基类来实现这个。 - Will Vousden
@WillVousden - 这将减少大量的语法。 - ChaosPandion
我会将属性改为方法。这种设计让我感觉AlgorithmItem正在持有SymmetricAlgorithm的实例。 - ChaosPandion
@ChaosPandion 我也同意这个观点。 - armen.shimoon
这就是我选择的,感谢您让我接触到新事物。 - user1657838

2
我的第一反应是给你提供工厂方法抽象工厂模式的维基百科链接(我还是做了),但既然你说你是初学者,我们就不要一开始就使用大杀器了。
基本上,你需要找到所有加密算法的共同特点,并创建一个方法来返回具有这个共同特点的对象实例。在C#中,这种特点的表现形式可以是抽象类或接口,而你很幸运,所有选择的加密都派生自SymmetricAlgorithm(“幸运”可能是对System.Security.Cryptography设计人员的侮辱,但出于说明的目的,我相信他们会原谅我的;)。
因此,只需通过引入一个新方法来重构您的代码,可能沿着这些线路:
private SymmetricAlgorithm GetAlgorithm(int index)
{
  switch (index)
  {
    case 0:
      return Aes.Create();
    case 1:
      return DES.Create();
    case 2:
      return Rijndael.Create();
    default:
      throw new NotSupportedException("unknown algorithm");
  }
}

你可以很容易地从你的代码中了解如何使用这个新方法。

我很欣赏这个设计的简洁性。 - ChaosPandion
@ChaosPandion:谢谢。我觉得其他答案可能更符合面向对象编程的要求,但对于初学者来说可能会有些困难。一步一个脚印,慢慢培养他们的兴趣吧 :) - Alan
非常感谢!我认为这会起作用,而且switch case是我知道的东西!C#与我所知道的编程语言非常不同,所以需要一些时间来适应。感谢您的支持。 - user1657838
@user1657838:不用谢,我很高兴能帮到你。 - Alan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接