C#利用反射(Reflection)进行SHA1和MD5的哈希(Hash)加密

!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。

最近在ASP.NET项目中用到的,主要是对用户密码进行哈希加密,传统编程进行的两种哈希加密方式一般如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Text;
using System.Security.Cryptography;
 
namespace ConsoleApplication1
{
    class Program
    {
        public static string ComputeSHA1Hash(string str)
        {
            using (SHA1CryptoServiceProvider
                sha1Csp = new SHA1CryptoServiceProvider())
            {
                str = Convert.ToBase64String(
                        sha1Csp.ComputeHash(
                        Encoding.UTF8.GetBytes(str)
                        )
                    );
                sha1Csp.Clear();
            }
            return str;
        }
 
        public static string ComputeMD5Hash(string str)
        {
            using (MD5CryptoServiceProvider
                md5Csp = new MD5CryptoServiceProvider())
            {
                str = Convert.ToBase64String(
                        md5Csp.ComputeHash(
                        Encoding.UTF8.GetBytes(str)
                        )
                    );
                md5Csp.Clear();
            }
            return str;
        }
 
        static void Main(string[] args)
        {
            System.Console.WriteLine(ComputeSHA1Hash(@"http://wangye.org"));
            System.Console.WriteLine(ComputeMD5Hash(@"http://wangye.org"));
        }
    }
}

通过代码可以很明显的看出,我们主要引入System.Security.Cryptography的命名空间,然后调用其SHA1CryptoServiceProvider进行SHA1哈希或者调用MD5CryptoServiceProvider进行MD5哈希,当然由于哈希所需要的参数是字节型的,所以还需要将字符串进行一次字节编码,为了更好的兼容性,我们这里选择Encoding.UTF8.GetBytes进行UTF8编码,然后将哈希编码好的字节码再转换为Base64,至此整个哈希编码完成。

大家可能看到这两个函数比较类似,有没有什么办法将它们整合一下,变得更通用呢?对了,你可能想到了反射(Reflection),确实我们可以引入反射机制,从而让我们的代码更精简,更通用。反射功能需要引入System.Reflection命名空间,然后查找SHA1CryptoServiceProvider和MD5CryptoServiceProvider的定义,发现其共同继承了HashAlgorithm这个类,这么说这个类可以作为一个通用的类型。Assembly.GetAssembly().CreateInstance()的方式创建对象,那么GetAssembly()的参数类型该如何获得呢?我们可以通过System.Type.GetType(“命名空间名称”)这个方法得到,比如说System.Type.GetType(“System.Security.Cryptography.SHA1CryptoServiceProvider”)将得到SHA1CryptoServiceProvider的类型,那么SHA1就可以独立出来,就像System.Type.GetType(“System.Security.Cryptography.”+param+”CryptoServiceProvider”),param如果是SHA1,那么就是SHA1的Provider,如果是MD5,那么就是MD5的Provider。恩,先简单介绍到这里,具体的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Text;
using System.Security.Cryptography;
using System.Reflection;
 
namespace ConsoleApplication1
{
    class Program
    {
        public static string ComputeHash(
            string str,       // 要哈希的字符串
            string hashType,  // 哈希的类型SHA1、MD5
            string encodeType // 编码模式ASCII、UTF8、
                              // 如果为null将采用Default编码
            )
        {
 
            encodeType = string.IsNullOrEmpty(encodeType) ?
                "Default" : encodeType.Trim();
 
            string []assemblyName = new string[2] {
                "System.Security.Cryptography." +
                hashType.Trim().ToUpper() +
                "CryptoServiceProvider",
                "System.Text.Encoding"};
 
            using (HashAlgorithm
                Csp = Assembly.GetAssembly(
                System.Type.GetType(assemblyName[0]))
                .CreateInstance(assemblyName[0]) as HashAlgorithm)
            {
 
                str = Convert.ToBase64String(
                    Csp.ComputeHash(
                    (System.Type.GetType(assemblyName[1])
                    .GetProperty(encodeType)
                    .GetValue(null, null) as Encoding)
                    .GetBytes(str))
                    );
                Csp.Clear();
            }
            return str;
        }
 
        static void Main(string[] args)
        {
            System.Console.WriteLine(
                ComputeHash(@"http://wangye.org", "SHA1", "UTF8")
                );
            System.Console.WriteLine(
                ComputeHash(@"http://wangye.org", "MD5", "UTF8")
                );
        }
    }
}

END

若无特别说明,本网站文章均为原创,原则上这些文章不允许转载,但是如果阁下是出于研究学习目的可以转载到阁下的个人博客或者主页,转载遵循创作共同性“署名-非商业性使用-相同方式共享”原则,请转载时注明作者出处谢绝商业性、非署名、采集站、垃圾站或者纯粹为了流量的转载。谢谢合作!
请稍后...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*