来源:http://www.2cto.com/Article/201601/488162.html

在前一篇文章《设计安全的账号系统的正确姿势》中,主要提出了一些设计的方法和思路,并没有给出一个更加具体的,可以实施的安全加密方案。经过我仔细的思考并了解了目前一些方案后,我设计了一个自认为还比较安全的安全加密方案。本文主要就是讲述这个方案,非常欢迎和期待有读者一起来讨论。

首先,我们明确一下安全加密方案的终极目标:

即使在数据被拖库,代码被泄露,请求被劫持的情况下,也能保障用户的密码不被泄露。

说具体一些,我们理想中的绝对安全的系统大概是这样的:

首先保障数据很难被拖库。 即使数据被拖库,攻击者也无法从中破解出用户的密码。 即使数据被拖库,攻击者也无法伪造登录请求通过验证。 即使数据被拖库,攻击者劫持了用户的请求数据,也无法破解出用户的密码。

如何保障数据不被拖库,这里就不展开讲了。首先我们来说说密码加密。现在应该很少系统会直接保存用户的密码了吧,至少也是会计算密码的 md5 后保存。md5 这种不可逆的加密方法理论上已经很安全了,但是随着彩虹表的出现,使得大量长度不够的密码可以直接从彩虹表里反推出来。

所以,只对密码进行 md5 加密是肯定不够的。聪明的程序员想出了个办法,即使用户的密码很短,只要我在他的短密码后面加上一段很长的字符,再计算 md5 ,那反推出原始密码就变得非常困难了。加上的这段长字符,我们称为盐(Salt),通过这种方式加密的结果,我们称为 加盐 Hash 。比如:

salt

上一篇我们讲过,常用的哈希函数中,SHA-256、SHA-512 会比 md5 更安全,更难破解,出于更高安全性的考虑,我的这个方案中,会使用 SHA-512 代替 md5 。

salt

通过上面的加盐哈希运算,即使攻击者拿到了最终结果,也很难反推出原始的密码。不能反推,但可以正着推,假设攻击者将 salt 值也拿到了,那么他可以枚举遍历所有 6 位数的简单密码,加盐哈希,计算出一个结果对照表,从而破解出简单的密码。这就是通常所说的暴力破解。

为了应对暴力破解,我使用了加盐的慢哈希。慢哈希是指执行这个哈希函数非常慢,这样暴力破解需要枚举遍历所有可能结果时,就需要花上非常非常长的时间。比如:bcrypt 就是这样一个慢哈希函数:

bcrypt

通过调整 cost 参数,可以调整该函数慢到什么程度。假设让 bcrypt 计算一次需要 0.5 秒,遍历 6 位的简单密码,需要的时间为:((26 * 2 + 10)^6) / 2 秒,约 900 年。

好了,有了上面的基础,来看看我的最终解决方案:

password_secutity

上图里有很多细节,我分阶段来讲:

1. 协商密钥

基于非对称加密的密钥协商算法,可以在通信内容完全被公开的情况下,双方协商出一个只有双方才知道的密钥,然后使用该密钥进行对称加密传输数据。比如图中所用的 ECDH 密钥协商。

2. 请求 Salt

双方协商出一个密钥 SharedKey 之后,就可以使用 SharedKey 作为 AES 对称加密的密钥进行通信,客户端传给服务端自己的公钥 A ,以及加密了的用户ID(uid)。服务端从数据库中查找到该 uid 对于的 Salt1 和 Salt2 ,然后再加密返回给客户端。

注意,服务端保存的 Salt1 和 Salt2 最好和用户数据分开存储,存到其他服务器的数据库里,这样即使被 SQL 注入,想要获得 Salt1 和 Salt2 也会非常困难。

3. 验证密码

这是最重要的一步了。客户端拿到 Salt1 和 Salt2 之后,可以计算出两个加盐哈希:

SaltHash1 = bcrypt(SHA512(password), uid + salt1, 10)SaltHash2 = SHA512(SaltHash1 + uid + salt2)

使用 SaltHash2 做为 AES 密钥,加密包括 uid,time,SaltHash1,RandKey 等内容传输给服务端:

Ticket = AES(SaltHash2, uid + time + SaltHash1 + RandKey)AES(SharedKey, Ticket)

服务端使用 SharedKey 解密出 Ticket 之后,再从数据库中找到该 uid 对应的 SaltHash2 ,解密 Ticket ,得到 SaltHash1 ,使用 SaltHash1 重新计算 SaltHash2 看是否和数据库中的 SaltHash2 一致,从而验证密码是否正确。

校验两个哈希值是否相等时,使用时间恒定的比较函数,防止试探性攻击。

time 用于记录数据包发送的时间,用来防止录制回放攻击。

4. 加密传输

密码验证通过后,服务端生成一个随机的临时密钥 TempKey(使用安全的随机函数),并使用 RandKey 做为密钥,传输给客户端。之后双方的数据交互都通过 TempKey 作为 AES 密钥进行加密。

假设被拖库了

以上就是整个加密传输、存储的全过程。我们来假设几种攻击场景:

假设数据被拖库了,密码会泄露吗?

数据库中的 Salt1 ,Salt2 , SaltHash2 暴露了,想从 SaltHash2 直接反解出原始密码几乎是不可能的事情。

假设数据被拖库了,攻击者能不能伪造登录请求通过验证?

攻击者在生成 Ticket 时,需要 SaltHash1 ,但由于并不知道密码,所以无法计算出 SaltHash1 ,又无法从 SaltHash2 反推 SaltHash1 ,所以无法伪造登录请求通过验证。

假设数据被拖库了,攻击者使用中间人攻击,劫持了用户的请求,密码会被泄露吗?

中间人拥有真实服务器所有的数据,仿冒了真实的 Server ,因此,他可以解密出 Ticket 中的 SaltHash1 ,但是 SaltHash1 是无法解密出原始密码的。所以,密码也不会被泄露。

但是,中间人攻击可以获取到最后的 TempKey ,从而能监听后续的所有通信过程。这是很难解决的问题,因为在服务端所有东西都暴露的情况下,中间人假设可以劫持用户数据,仿冒真实 Server , 是很难和真实的 Server 区分开的。解决的方法也许只有防止被中间人攻击,保证 Server 的公钥在客户端不被篡改。

假设攻击已经进展到了这样的程度,还有办法补救吗?有。由于攻击者只能监听用户的登录过程,并不知道真实的密码。所以,只需要在服务端对 Salt2 进行升级,即可生成新的 SaltHash2 ,从而让攻击者所有攻击失效。

具体是这样的:用户正常的登录,服务端验证通过后,生成新的 Salt2 ,然后根据传过来的 SaltHash1 重新计算了 SaltHash2 存入数据库。下次用户再次登录时,获取到的是新的 Salt2 ,密码没有变,同样能登录,攻击者之前拖库的那份数据也失效了。

Q & A

使用 bcrypt 慢哈希函数,服务端应对大量的用户登录请求,性能承受的了吗?

该方案中,细心一点会注意到, bcrypt 只是在客户端进行运算的,服务端是直接拿到客户端运算好的结果( SaltHash1 )后 SHA-512 计算结果进行验证的。所以,把性能压力分摊到了各个客户端。

为什么要使用两个 Salt 值?

使用两个 Salt 值,是为了防止拖库后,劫持了用户请求后将密码破解出来。只有拥有密码的用户,才能用第一个 Salt 值计算出 SaltHash1 ,并且不能反推回原始密码。第二个 Salt 值可以加大被拖库后直接解密出 SaltHash1 的难度。

为什么要动态请求 Salt1 和 Salt2 ?

Salt 值直接写在客户端肯定不好,而且写死了要修改还得升级客户端。动态请求 Salt 值,还可以实现不升级客户端的情况下,对密码进行动态升级:服务端可定期更换 Salt2 ,重新计算 SaltHash2 ,让攻击者即使拖了一次数据也很快处于失效状态。

数据库都已经全被拖走了,密码不泄露还有什么意义呢?

其实是有意义的,正如刚刚提到的升级 Salt2 的补救方案,用户可以在完全不知情的情况下,不需要修改密码就升级了账号体系。同时,保护好用户的密码,不被攻击者拿去撞别家网站的库,也是一份责任。

被脱裤也不怕,密码安全可以这样保障相关推荐

  1. 关于51CTO被脱裤,几点关于密码的建议

    下午刷微博的时候看到了51CTO被脱裤的消息,开始没当回事.然后在晚上的时候想着开邮箱看看(平时把邮箱的推送关了),结果收到了两封异常登陆的邮件,突然感觉有点冒冷汗.之前看过写安全方面的文章,其实这互 ...

  2. 开房信息被黑客“脱裤”以后…

    点击上方"程序人生",选择"置顶公众号" 第一时间关注程序猿(媛)身边的故事 作者 特大妹 如需转载,请联系原作者授权. 这两天 特大妹注意到一条大消息 ▼ 某 ...

  3. mysql盲注脱裤_BT5下使用SQLMAP入侵加脱裤 -电脑资料

    早就听说BT5下的sqlmap功能很强大,今天终于下决心拒绝DOTA和苍老师的诱惑,静下心来研究研究这个传说中的sqlmap!由于在虚拟机里面用的 ,我直接在真机上也装了个BT5的系统,嘻嘻··,那感 ...

  4. mysql盲注脱裤_白帽子挖洞—SQL注入篇

    0x00介绍 SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到 ...

  5. mysql盲注脱裤_记一次猥琐的脱裤

    简介 环境 php+pdo+mysql+linux FUCK IT 因为是pdo,所以支持多行,一开始只用了时间盲注跑了用户表的列出来,然后可以通过多行语句执行 updaet user set ema ...

  6. 上海脱裤犀利姐:不要迷恋姐,姐只是憋不住

    不要迷恋姐,姐只是憋不住 近日,一位妇女成了人们茶余饭后的热门谈资,而让她迅速窜红的却是一场大失文雅的"脱裤门".光天化日之下,美女公然在繁华的徐汇商业街边脱裤小解,城市管理者上前 ...

  7. 国外刷卡不需密码 网友支招保障信用卡安全

    国外刷卡不需密码 网友支招保障信用卡安全   去境外网站上购物,东西正宗价格又实惠,成为目前不少80后90后的首选."我在美国亚马逊(微博)网站买了双靴子,加上转运的运费,价格还是比国内专柜 ...

  8. 仿5173游戏交易平台系统SQL注入(可直接脱裤)+Getshell

    最近没事登登好几年前玩过的游戏看看,发现有人喊高价收号,这一看就是骗子,这等骗子还想骗我?我就来看看这逗逼是怎么骗人的,结果发现这人给了一个说是 5173平台交易的网站,叫我直接把号的信息填上去然后填 ...

  9. 【玩转ms17-010】mysql数据库-脱裤实践

    一.背景 学习了两周的msf 还没怎么实战过,有点手痒,顺带手上任务差不多完成了,就借此机会去实践一把! 二.上手 1.指定网段扫描是否存在ms17-010漏洞 1.Use auxiliary/sca ...

最新文章

  1. TX2安装中文输入法
  2. CVPR 2020 Oral 出炉!5篇 Oral 论文抢先看
  3. android 2.0 软件,Apeaksoft Android Toolkit
  4. 解决AJAX CalendarExtender控件不显示中文的情况(转帖博客园某人(不好意思,实在是没有找到您的尊姓大名,感谢一下!))...
  5. Java几种常见的编码方式
  6. 2013年中国数据库大会PPT
  7. Algorithm:C++语言实现之概率算法相关问题(计算机中的概率事件、C语言中的随机事件、产生二维随机数、圆内均匀取点)
  8. 7号团队-团队任务3:每日例会(2018-12-05)
  9. yum php devel_yum源里找不到 php54w-devel,求可用yum源
  10. 112家it公司薪水
  11. MySQL必会企业面试题
  12. c语言缓冲池管理算法,操作系统复习资料
  13. 深度学习-函数-tf.nn.embedding_lookup 与tf.keras.layers.Embedding
  14. c++ 使用nacos_超赞!用阿里开源的Nacos做SpringCloud注册中心真贴心...
  15. python 数学计算库_数学计算工具库-Numpy
  16. 银河帝国----基地与地球
  17. 国际化中英文切换,英文内容长度过长的解决问题
  18. 固态和机械硬盘组raid_SSD+机械硬盘Raid 0成最佳搭配?_浦科特 PX-M5Pro_固态硬盘评测-中关村在线...
  19. Perl操作excel2007的模块
  20. FFMpeg编译之路

热门文章

  1. video.js兼容微信浏览器,(播放.m3u8视频源)解决微信浏览器黑屏问题
  2. 网站建设的交互设计原则是什么
  3. 1.3 计算机的性能指标
  4. c语言入门for语句,c语言for语句
  5. 为什么有的人思维缜密,滴水不漏,逻辑通透?
  6. 中国隧道掘进机(TBM)行业需求状况与投资价值评估报告2022-2027年
  7. 基于探路者算法的函数寻优算法
  8. android 查询快捷方式,android桌面快捷方式的创建和查询
  9. Deep Label Distribution Learning With Label Ambiguity
  10. java接口中只能定义常量和抽象方法_java基础19. 下列有关接口的叙述错误的是哪项?() A.接口中只能包含抽象方法和常量 B.一个类可以实现多个接口...