当前位置: 首页 > news >正文

[ZT]互联网网站应该如何存储密码?

原文载于知乎。http://www.zhihu.com/question/20479856

 

13

韩竹,云存储服务坚果云的联合创始人。

13 票,来自  王峰、廖小树、任军  更多
刚好坚果云博客写了一篇这样的文章【1】, 讲述如何存储密码才安全。完整内容可以查看【1】原文。

简单而言,存储bcrypt, scrypt等算法输出的内容,不要用salted hash的方式存储密码,不要用加密的方式存储密码,当然,更不要明文存储。

顺带说一句,任何情况下尽可能的不要使用md5算法,而使用SHA系列的哈希算法。因为md5算法在很多地方被证明是很容易冲突的【2】,另外md5的性能优势也完全可以忽略不计。

为什么不能加密存储?
加密存储的方式其实和明文存储没有区别。密码加密后一定能被解密获得原始密码,因此,该网站一旦数据库泄露,所有用户的密码本身就大白于天下。另外,管理员也存在获取原始密码,利用同样的帐号登陆其他互联网服务的可能。

为什么不能用Hash存储? 
单向Hash算法(MD5, SHA1, SHA256等)可以保证管理员几乎不能恢复原始密码。但它有两个特点:
1)从同一个密码进行单向哈希,得到的总是唯一确定的摘要
2)计算速度快。随着技术进步,尤其是显卡在高性能计算中的普及,一秒钟能够完成数十亿次单向哈希计算

结合上面两个特点,考虑到多数人所使用的密码为常见的组合,攻击者可以将所有密码的常见组合进行单向哈希,得到一个摘要组合, 然后与数据库中的摘要进行比对即可获得对应的密码。这个摘要组合也被称为rainbow table【3】。
更糟糕的是,一个攻击者只要建立上述的rainbow table,可以匹配所有的密码数据库。

为什么不能用Salt + Hash的方式存储?
将明文密码混入“随机因素“,然后进行单向哈希后存储,也就是所谓的”Salted Hash”。 
这个方式相比上面的方案,最大的好处是针对每一个数据库中的密码,都需要建立一个完整的rainbow table进行匹配。 因为两个同样使用“passwordhunter”作为密码的账户,在数据库中存储的摘要完全不同。
10多年以前,因为计算和内存大小的限制,这个方案还是足够安全的,因为攻击者没有足够的资源建立这么多的rainbow table。 但是,在今日,因为显卡的恐怖的并行计算能力,这种攻击已经完全可行。

为什么bcrypt, scrypt等算法能保证密码存储的安全性?
这类算法有一个特点,算法中都有个因子,用于指明计算密码摘要所需要的资源和时间,也就是计算强度。计算强度越大,攻击者建立rainbow table越困难,以至于不可继续。

也就是说,故意延长一个密码匹配的计算时间,如果一个密码匹配需要1秒钟,那么匹配1000万个密码组合就需要115天,这个开销就非常大。

另外,这类算法也可以保证即使计算能力不断提高,只要调整算法中的强度因子,密码仍然不可能被轻易的攻破,同时不影响已有用户的登陆。关于这些算法的具体优劣,请参考【1】

【1】  blog.jianguoyun.com/...
【2】 marc-stevens.nl/research...
【3】 en.wikipedia.org/wiki...

转载于:https://www.cnblogs.com/zhangjiang/archive/2012/09/17/2688252.html

相关文章:

  • java 遍历方法 及 数组,ArrayList,HashMap,HashSet的遍历
  • Joda-Time 简介
  • 一个项目push到多个远程Git仓库
  • 每日一练No.5
  • linux shell通配符、元字符、转义符
  • 超实用的8个Linux命令行性能监测工具
  • P2667 超级素数
  • crunchbang10折腾过程
  • 半自动化安装dns
  • crontab 不能执行的原因
  • 在CentOS上安装Maven3
  • Django:(博客系统)添加文章(中文)出现UnicodeEncodeError乱码
  • iReport 编辑的报表,在jsp中导出到PDF的代码
  • js-scroll判断页面是向上滚动还是向下滚动
  • jQGrid API
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • angular学习第一篇-----环境搭建
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JSONP原理
  • leetcode98. Validate Binary Search Tree
  • leetcode讲解--894. All Possible Full Binary Trees
  • mysql外键的使用
  • Solarized Scheme
  • 计算机常识 - 收藏集 - 掘金
  • 每天10道Java面试题,跟我走,offer有!
  • 前端路由实现-history
  • 微信小程序填坑清单
  • 微信小程序--------语音识别(前端自己也能玩)
  • 温故知新之javascript面向对象
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • #HarmonyOS:基础语法
  • #Z2294. 打印树的直径
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (第27天)Oracle 数据泵转换分区表
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .Net接口调试与案例
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • :not(:first-child)和:not(:last-child)的用法
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [2016.7.Test1] T1 三进制异或
  • [Android实例] 保持屏幕长亮的两种方法 [转]
  • [C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型
  • [C语言]——分支和循环(4)
  • [Everyday Mathematics]20150130
  • [Git 1]基本操作与协同开发