建议114:MD5不再安全

MD5不再安全不是就算法本身而言的。如果从可逆性的角度出发,MD5值不存在被破解的可能性。

MD5被广泛应用于密码验证和消息完整性验证。假设新注册一个用户,当注册用户的密码第一次被存储到数据库时,往往会将其转换为MD5值存储:

        static string GetMd5Hash(string input){using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()){return BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(input))).Replace("-", "");}}static void Main(string[] args){string source = "liming's key";string hash = GetMd5Hash(source);Console.WriteLine("保存密码原文:{0}的MD5值:{1}到数据库。",source,hash);Console.Read();}

输出为:

保存密码原文:liming's key的MD5值:B222558FD330454B08878C61FD595121到数据库。

如果MD5值存储在数据库中,当用户登录时,只需要验证MD5就可以检查用户输入的密码是否正确。如下:

        static void Main(string[] args){Console.WriteLine("请输入密码,按回车键结束……");string source = Console.ReadLine();if (VerifyMd5Hash(source, "B222558FD330454B08878C61FD595121")){Console.WriteLine("密码正确,准许登录系统。");}else{Console.WriteLine("密码有误,拒绝登录。");}}    static bool VerifyMd5Hash(string input, string hash){string hashOfInput = GetMd5Hash(input);StringComparer comparer = StringComparer.OrdinalIgnoreCase;return comparer.Compare(hashOfInput, hash) == 0 ? true : false;}

输出为:

请输入密码,按回车键结束……
liming's key
密码正确,准许登录系统。

处于隐私保护的目的,所以不直接存储密码。即便是一个银行系统,我们也不想让银行的后台管理人员看到我们的密码。而通过MD5值来校验,就可以确保无人可以查看或破解我们的密码,也达到了密码验证的目的。虽然有人可能会质疑,MD5的算法不是多对一的吗?也就是说,可能存在一个另外的密码,求出来的MD5值和我这个密码是一样的啊。但是,在实际应用场合中,这个概率会很小,小到可以忽略不计。

既然到目前为止所说的都是MD5的优点,那么,为什么说MD5是不安全的呢?因为,这个世界上还有一种方法叫做穷举法。由于用户安全意识先对薄弱,所以他们设置的密码很有可能是简单的数字集合。这种情况下如果破解密码。穷举法会派上很大的用处。以密码“8888”为例,测试下我们用穷举法破解所需时间:

        static void Main(string[] args){Console.WriteLine("开始穷举法破解用户密码……");string key = string.Empty;Stopwatch watch = new Stopwatch();watch.Start();for (int i = 0; i < 9999; i++){if (VerifyMd5Hash(i.ToString(), "CF79AE6ADDBA60AD018347359BD144D2")){key = i.ToString();break;}}watch.Stop();Console.WriteLine("密码已破解,为:{0},耗时{1}毫秒。", key, watch.ElapsedMilliseconds);}

输出为:

开始穷举法破解用户密码……
密码已破解,为:8888,耗时124毫秒。

可见,如果我们的密码过于简单,计算机甚至都不需要1秒的时间就能完成暴力破解。当然,这种算法不是针对MD5的可逆破解,而是非常愚蠢的穷举。现在,已经有很多免费的商业的MD5字典库,存储了相当数量字符串的MD5值,我们只要提交一个MD5值进去,立刻就可以得到他的原文,只要这个原文不是非常复杂。所以,从这方面来说,MD5不再安全。

因此,我们需要找一个办法来改进MD5求值了。目前,最通用的算法是多次使用MD5值发。我们修改一下GetMd5Hash方法,代码如下:

        static string GetMd5Hash(string input){string hashKey = "Aa1@#$,.Klj+{>.45oP";using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()){string hashCode = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(input))).Replace("-", "") + BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(hashKey))).Replace("-", "");return BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(hashCode))).Replace("-", "");}}

在改进后的方法中,我们首先设计了一个足够复杂的密码hashKey,然后将它的MD5值和用户输入密码的MD5值相加,再求一次MD5值作为返回值。经过这个过程以后,密码的长度就够了,复杂度也够了,要想通过穷举法来得到真正的密码成本也就大大增加了。

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

建议114:MD5不再安全相关推荐

  1. 方法:大学生找工作的八大建议...让你不再迷茫

    今天是个不建议出门开车.适合睡懒觉的"好"天气. 上班压抑着,一天不知道在忙什么,就是在瞎忙.敲打键盘的我伴随着部门领导在隔壁办公室的讲话而心情忐忑,总是望着办公室的门缝,盯着领导 ...

  2. 编写高质量代码改善C++程序的150个建议

    第一部分 语法篇   第1章   从C继承而来的 建议0:不用让main函数返回void main函数的返回类型是int,不是void或其它类型. 建议1:区分0的4种面孔          (1). ...

  3. 114和118114

    网上流传一个笑话,说一个科学家极力向人推介他的新发明: "我发明的手机可高级了,什么收音机.录音机.mp3.电子书.照相机等功能一应俱全,还能当GPS使用.不光如此,在走夜路遇到坏人时,你按 ...

  4. [转]MD5(1)-安全性与原理

    转载请注明出处 http://www.paraller.com 原文排版地址 点击获取更好阅读体验 转载: http://blog.sina.com.cn/s/blog_77e8d1350100wfc ...

  5. java 151建议_编写高质量代码改善java程序的151个建议——导航开篇

    前言 系列文章: 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,惨不忍睹是吧.确实,人和代码一样都在成长,都在变好当中.有时候只是实现功能的编程,长 ...

  6. Shiro框架:Shiro简介、登陆认证入门程序、认证执行流程、使用自定义Realm进行登陆认证、Shiro的MD5散列算法

    一.Shiro介绍: 1.什么是shiro: (1)shiro是apache的一个开源框架,是一个权限管理的框架,实现用户认证.用户授权. (2)spring中有spring security,是一个 ...

  7. 关于玻璃体手术的最终建议

    ①激光消融 ②定点FOV 目前对于两项手术以及相关升级版手术, 均不建议去做,不再劝阻执意去做手术的人. 成年人只筛选.不教育,否则成本巨大.

  8. php中sha1,PHP中sha1()函数和md5()函数的绕过

    相信大家都知道,sha1函数和md5都是哈希编码的一种,在PHP中,这两种编码是存在绕过漏洞的. PHP在处理哈希字符串时,会利用"!="或"=="来对哈希值进 ...

  9. 应用密码学的笑话之MD5+Salt不安全

    这段时间诸多爆库的新闻,里面有许多饶有趣味的事情.那些用简单密码,或者一个密码走天下的笑话就不说了,咱说点有内涵的.(这篇文章是给IT界的人看的,如果你看不懂,我会准备一个简单的"如何辨别密 ...

  10. 安全随笔1:谨慎一次MD5值的可被穷举性

    安全随笔1:谨慎一次MD5值的可被穷举性 MD5不再安全不是从算法本身而言.如果从可逆性角度出发, MD5值不存在被破解的可能性.MD5的算法公式如下: R=H(S) 该公式指出:对于给定的一个源内容 ...

最新文章

  1. SAP WM 2-Step Picking的TO单据特殊的地方
  2. github关联域名,创建个人网站教程终结篇
  3. 交换两个数组的元素使之总和的差值最小
  4. OpenCV线特征Line Features
  5. java merge css_一句命令快速合并 JS、CSS
  6. iview实现多文件上传,前段到后台
  7. mysql连接idea详细教程_idea配置连接数据库的超详细步骤
  8. python编写字符串查找函数_Python 简明教程 --- 8,Python 字符串函数
  9. django 1.8 官方文档翻译:6-3 Django异常
  10. 推荐10款 好用的 Jquery 评分插件
  11. asp.net mvc4 设置build项目时,编译view页面
  12. 漫画:“架构师”小赵的故事
  13. 基于Pygame框架和蒙特卡洛树搜索的“走四棋儿”人机对战小游戏(附编程详解和代码)
  14. Word宏与VBA/VB
  15. FusionSphere 物理CPU与VCPU的关系梳理总结
  16. sdfasfasdf
  17. maven+junit生成报告
  18. java中对数据进行脱敏操作(证件号,手机号,移动电话,邮箱)
  19. 自动定时任务不要整点运行
  20. kafka究竟是干嘛的?

热门文章

  1. 【Love2d从青铜到王者】第十六篇:Love2d之动画(Animation)
  2. 解决go get时,遇到unrecognized import path的问题
  3. (附源码)python飞机票销售系统 毕业设计 141432
  4. Python 高级:人工智能概述
  5. 30行代码实现微信自动回复机器人
  6. 台式计算机有线无线网卡设置,电脑无线网卡如何使用 电脑外置无线网卡详细使用图文教程...
  7. single无效,使用maxLines
  8. webpack ——css兼容性处理
  9. CSS背景颜色之奇技淫巧
  10. web网页前端学习 案例一之制作网页表格