MD5加密 Via C#

本文PDF下载(转载请注明出处)

近来在项目中用到了MD5加密技术,用来将用户的登录密码加密后,存入数据库保存。例如:用户输入“123456”,加密后的字符串即为“e10adc3949ba59abbe56e057f20f883e”。

注意,加密后的字符串是不可逆的,即遗失密码后只能重置,不能解密出实际密码。下面介绍MD5的一些知识:

历史与密码学

  • 1992年8月Ronald L. Rivest在向IETF提交了一份重要文件,描述了这种算法的原理,由于这种算法的公开性和安全性,在90年代被广泛使用在各种程序语言中,用以确保资料传递无误等。
  • MD5由MD4、MD3、MD2改进而来,一度主要增强算法复杂度和不可逆性。
  • MD5一度被广泛应用于安全领域。但是由于MD5的弱点被不断发现以及计算机能力不断的提升,现在已经可以构造两个具有相同MD5的信息,使本算法不再适合当前的安全环境。目前,MD5计算广泛应用于错误检查。例如在一些BitTorrent下载中,软件通过计算MD5和检验下载到的碎片的完整性。

弱点

  • MD5较老,散列长度通常为128位,随着计算机运算能力提高,找到“碰撞”是可能的。因此,在安全要求高的场合不使用MD5。
  • 2004年,王小云证明MD5数字签名算法可以产生碰撞。2007年,Marc Stevens,Arjen K. Lenstra和Benne de Weger进一步指出通过伪造软件签名,可重复性攻击MD5算法。研究者使用前缀碰撞法(chosen-prefix collision),使程序前端包含恶意程序,利用后面的空间添上垃圾代码凑出同样的MD5 Hash值。
  • 2008年,荷兰埃因霍芬技术大学科学家成功把2个可执行文件进行了MD5碰撞,使得这两个运行结果不同的程序被计算出同一个MD5。2008年12月一组科研人员通过MD5碰撞成功生成了伪造的SSL证书,这使得在https协议中服务器可以伪造一些根CA的签名。

下面的代码展示了如何将一个字符串使用MD5加密:

// 计算字符串的 MD5 哈希值,并将该哈希作为 32 字符的十六进制格式字符串返回。

public string GetMD5Hash(string input)

{

    // 创建一个MD5CryptoServiceProvider对象的新实例。

    MD5 md5Hasher = MD5.Create();



    // 将输入的字符串转换为一个字节数组并计算哈希值。

    byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));



    //创建一个StringBuilder对象,用来收集字节数组中的每一个字节,然后创建一个字符串。

    StringBuilder sBuilder = new StringBuilder();



    // 遍历字节数组,将每一个字节转换为十六进制字符串后,追加到StringBuilder实例的结尾

    for (int i = 0; i < data.Length; i++)

    {

        sBuilder.Append(data[i].ToString("x2"));

    }



    // 返回一个十六进制字符串

    return sBuilder.ToString();

}

下面的代码展示了一个输入字符串经MD5转换后,是否等同于一个已加密的哈希值:

// 验证输入字符串经MD5转换后,是否等同于一个哈希值

public bool VerifyMd5Hash(string input, string hash)

{

    // 将输入字符串MD5加密

    string hashOfInput = GetMD5Hash(input);



    // 创建一个StringComparer实例来比较两个哈希值

    // StringComparer.OrdinalIgnoreCase:获取 StringComparer 对象

    // ,该对象执行不区分大小写的序号字符串比较。

    StringComparer comparer = StringComparer.OrdinalIgnoreCase;



    return comparer.Compare(hashOfInput, hash) == 0;

}

在上述两段代码中,GetMD5Hash方法常用于用户注册,VerifyMd5Hash方法常用于用户登录。

下面,介绍下StringComparer对象。它表示一种字符串比较操作,该操作使用特定的大小写以及基于区域性的比较规则或序号比较规则。它有6个常用静态属性可以获得实例:

名称

说明

CurrentCulture

该对象使用当前区域性的单词比较规则执行区分大小写的字符串比较。

CurrentCultureIgnoreCase

该对象使用当前区域性的单词比较规则执行不区分大小写的字符串比较。

InvariantCulture

该对象使用固定区域性的单词比较规则执行区分大小写的字符串比较。

InvariantCultureIgnoreCase

该对象使用固定区域性的单词比较规则执行不区分大小写的字符串比较。

Ordinal

该对象执行区分大小写的序号字符串比较。

OrdinalIgnoreCase

该对象执行不区分大小写的序号字符串比较。

然后,调用StringComparer实例的Compare方法,即可使用指定特性来比较两个字符串是否相等了。

你可能感兴趣的:(MD5加密)