懒人日记,摸鱼学了点儿加密知识
今天又是没有人差遣我干活的一天,这让我感到十分的无聊。虽然在公司组织学习方案中选择了WSO2认证相关的课题。。。但我的思维又开始胡乱地发散了。。导致今天的我十分想搞清楚这个问题:具备https加密的情况下,在前端对用户的密码进行加密到底有没有意义。
首先对于上述问题,在三个目的下有以下结论:
1、针对于提升系统安全性以及防止用户密码被拦截而言,如果已经有了https,那么在前端的加密可以说是——毫无意义。https已经保护了密码不被拦截,而万一https失效,加密也毫无用处。因为不管加不加密,都是把一段字符串发送给了服务器,对于黑客的重放攻击而言,无所谓是明文密码还是密文密码,反正直接复制过来拿去登录便是。。
2、针对于保护用户信息和隐私而言,前端加密还是有一定的意义的。因为现在普遍的情况就是用户都喜欢在很多网站上使用同样的密码,我自己也不例外。如果在前端对用户密码进行加密,黑客拦截到密码密文后,最多就是用它来登录当前的这个网站,同样的账号与密文拿去登录别的网站就没用了。即使另一个网站根本就没有前端加密,黑客拿着密文也没有简单有效的办法,除非两个网站的前端采用了完全相同的加密算法。当然,这一层保护还是防不住黑客使用暴力破解或者字典攻击等方式来破译出明文密码,但至少在很大程度上提高了他们的破译成本和时间。
3、在前端进行复杂逻辑的加密和处理,可以有效防止第三方的模拟登陆。这一点在下文具体说明。
此外,我还学习了几种提升系统安全性的技巧:
1、在用户注册时,服务端为用户生成随机salt(盐值)并存库(每个用户的salt不一样),每次登陆时使用前端传过来的密码(明文或密文都可)与salt拼接再进行hash来验证。万一服务器数据泄露,相同密码在数据库中的hash是不同的,这样黑客在进行暴力破解、字典攻击时就必须针对每一个密码进行操作,提高攻击成本。否则的话黑客破译了一个hash之后只要比对获取到的所有密文中是否有相同的值,所有相同的值都代表着这些用户的密码相同。
2、针对单纯的重放攻击,可以通过服务端每次更改盐值发送给前端,让前端带盐计算hash以在一定程度上避免。注意是一定程度上,因为在黑客具有拦截能力的情况下,黑客还是可以获取到每一次的盐值,然后分析前端加密算法进行字典攻击,但至少这样做使得黑客不得不进行字典攻击或爆破等手段,提高攻击成本。
现在再来说一下前文中说到的,前端加密具有防止第三方模拟登陆的作用:
这一段直接复制了知乎上的一个回答(链接:https://www.zhihu.com/question/25539382/answer/1270846719)
原文如下:
知乎的前端加密把用户的手机号和密码,再加上其它相关参数,比如时间戳,组合成一个 object。对这个 object 进行序列化,进行 Url Encoded,然后和一个 private key 拼在一起,用 sha1 算法算出 digest,然后再拼起来。再进行加密,加密的过程是一段奇怪的,混淆严重的 js 代码。加密的过程,只能把那段 js 代码整个打过来,做加密,具体怎么加密的,很难看懂。当然了,所有这一切,都发生在前端代码里,那些 key ,也都在前端代码里,然而知乎这么做,让模拟登录变得十分困难,从而阻止了很多潜在的第三方客户端的存在和机器人。
大家有兴趣可以去 Github 上看看知乎模拟登录的项目,几乎全部无效,都无法使用,对于知乎这种闭源的生态,从技术上遏制第三方应用和机器人的存在,这便是知乎前端登录加密的意义。
还有,比如爱奇艺的视频解码。
我当时看了一下爱奇艺的视频资源请求,请求来的数据,也是不能直接播放的,但是在爱奇艺的网站里能播放,说明爱奇艺前端代码会先将请求来的视频数据进行解密。
如果这个解密的代码搞得很乱很复杂,就让爱奇艺的视频模拟下载变得更加困难,这符合爱奇艺这种闭源会员制的网站的利益,但是大家有兴趣可以去看一下 youtube 的视频资源请求,请求来的数据是可以直接播放的,这一点和爱奇艺不同。
如果你的生态是开放的,像 Github 这样,把 API 公开,鼓励各种第三方客户端,那前端就没必要加密,如果你是闭源生态,巴不得所有人都从你这个入口进来,那关键部分做一下前端代码的加密混淆,会减少很多第三方应用。
结论:首先前端进行复杂逻辑的加密可以有效防止第三方的模拟登陆。现在很多网站不进行前端加密是为了节省计算性能开销,但如果把用户隐私和安全性放在第一位的话,前端加密(带salt的)是必不可少的。另外,整个系统的信息安全永远取决于保护最弱的环节。