当前位置:编程学习 > 网站相关 >>

结合反射技术实现多算法动态加密

这个题目,我姑且这样叫吧,照例,我们先来分析一下需求。
比如有一个设置密码的功能,但用户希望能够自己选择密码的加密算法,如MD5、HMAC、SHA1等,然后程序会根据用户所选择的算法对密码进行加密并存入数据库,同时在配置文件中记录下用户的选择。
按照一般的思路,我们可能会做一个分支判断,如
[csharp]
switch( 用户的选择 ) 

    case "MD5": 
              MD5 md5 = MD5.Create();..............        
              break; 
             ........... 

 
 
 
呵呵,其实我们不必要这样做,来,先来看看MD5、HMAC、SHA1、SHA384等类有什么共同的特征?
1、都是通过调用Create静态方法来创建一个实例,当然,像MD5这些类都是抽象类,是不能被实例化的。其实,它们都返回一个名为“算法名CryptoServiceProvider”的类实例,如MD5CryptoServiceProvider、SHA1CryptoServiceProvider等,这些类都是对算法计算的具体实现。
2、都是通过调用ComputeHash方法计算哈希值的。
 
而且,这些类都是位于同一个命名空间下,因些,根据不同的算法进行加密,唯一不同的是类名,也就是说,我们的代码只写一次就可以了,把代码封装在一个方法中,通过在参数中传递类名。
 
能做到这种功夫的,也就用到反射了,通过反射动态动调用类成员来完成。
 
 
[csharp]
/// <summary> 
/// 通过算法计算哈希值。 
/// </summary> 
/// <param name="className">算法类名</param> 
/// <param name="tcode">待加密的字符串</param> 
/// <returns>加密后的字节数组</returns> 
private byte[] ComputeHash(string className, string tcode) 

    byte[] bufRes = null; 
    // 加载程序集 
    Assembly asmby = Assembly.Load(@"mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); 
    Type myType = asmby.GetType("System.Security.Cryptography." + className, false, true); 
    if (myType != null) 
    { 
        // 得到与Create方法有关的MethodInfo 
        // GetMethod通过传入的Type数组的维数和类型来 
        // 判断获取哪个重载。 
        MethodInfo mdf=myType.GetMethod("Create",new Type[0]); 
        if (mdf != null) 
        { 
            object ob = null; 
            // 调用方法 
            ob = mdf.Invoke(null, null); 
            if (ob != null) 
            { 
                // 得到ComputeHash方法的MethodInfo 
                MethodInfo mfo = myType.GetMethod("ComputeHash", new Type[] { typeof(byte[]) }); 
                if (mfo!=null) 
                { 
                    // 调用方法 
                    bufRes = (byte[])mfo.Invoke(ob, new object[]{ 
                        Encoding.Default.GetBytes(tcode) 
                    }); 
                } 
            } 
        } 
    } 
    return bufRes; 

 
 
 
接着需要一个方法来把字节数组转为字符串。
 
 
[csharp]
/// <summary> 
/// 把字节数组转换为十六进制字符串。 
/// </summary> 
/// <param name="bf"></param> 
/// <returns></returns> 
private string ByteToStr(byte[] bf) 

    StringBuilder sb = new StringBuilder(); 
    foreach (byte b in bf) 
    { 
        sb.Append(b.ToString("x2")); 
    } 
    return sb.ToString(); 

 
 
 
然后,我们就可以在其它代码中使用了。
 
 
[csharp]
public partial class b : Form 

    public b() 
    { 
        InitializeComponent(); 
        comboBox1.Items.Add("HMAC"); 
        comboBox1.Items.Add("MD5"); 
        comboBox1.Items.Add("SHA1"); 
        comboBox1.Items.Add("SHA256"); 
        comboBox1.Items.Add("SHA384"); 
        comboBox1.Items.Add("SHA512"); 
        comboBox1.Items.Add("RIPEMD160"); 
        comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; 
        comboBox1.SelectedIndex = 0; 
    } 
 
    private void button1_Click(object sender, EventArgs e) 
    { 
        if (comboBox1.SelectedIndex == -1) 
        { 
            return; 
        } 
        try 
        { 
            byte[] bHash = ComputeHash(comboBox1.SelectedItem.ToString(), txtIn.Text); 
            if (bHash != null) 
            { 
                txtOut.Text = ByteToStr(bHash); 
          &n
补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,