前几天,我的一位朋友的apple账户被盗了。看到朋友给我发的几张图,顿时觉得盗取者的面目可憎。看下面的截图,可以说细思极恐。不仅抹掉了账户数据,更是直接远程操控,将账户的信息变更,让原有用户无法进行追回,只能任其宰割。而且看其所发的语势,受害者绝对不止一个,甚至已经形成了一条黑色的产业链。
好端端的,为什么账户会被盗呢?想起最近一次网络大事件就是京东被爆出的12G账户丢失了。果不其然,在问了朋友之后,apple的密码和京东的账户密码很相似,只是大小写不一样。
京东事后的解释称这次密码泄露,是由于structs2的漏洞引起的。当时爆发的时候可以说是受害者众多。鉴于密码被盗事件,细细想来,有几点想和大家分享一下。
关于密码保护主要有两大方面。一是系统存储方面。二是人为因素。(当然也涉及传输阶段:目前大部分的SSO系统都会使用cas、ldap服务等,或是通过将web服务改为https协议,亦或是将认证这一块交给第三方,比如Azure AD等,利用第三方的安全性来达到自身账户的安全。这里暂且不做讨论)。
1.系统存储方面
主要就是涉及如何安全的存储用户的密码。目的就是在即使hacker盗取了账户密码一时间也无法破解的效果。相信现在基本上已经看不到哪个系统还会存储用户的明文密码,至少都是加过密。不然hacker的一次简单的sql就会让你的系统脱离控制。说到加密,现如今加密算法主要有:BASE64、MD5、SHA1等。BASE64主要用于url地址跳转的加密,保证用户调用服务传参的行为是隐蔽的。还有个地方就是可用于移动端图片的适配问题。但是会导致数据加载缓慢。
MD5:是一种消息摘要算法。也是目前较为流行的加密算法。MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成—个128位散列值。虽说MD5应用广泛,而且是单向不可逆的,它的速度比SHA1快。但是这种可以通过字典、定位表或者彩虹表的方式破解。所谓的字典、彩虹等方式就是通过碰撞的方式间接的破解。由于MD5是不可逆的,那在我得到用户的加密密码(无规律的字符串)后,是无法知道原先的密码是什么。但是我可以正过来推理。我先记录下常见的密码,MD5加密后的hash值,然后形成字典集,当我要去破解用户密码的时候,我把得到的hash值放到字典集中检索。检索有结果,那我就map到对应的密码,也就知道了用户的密码。而定位表和彩虹表是为了加快检索速度,而将生成的hash值放在数据库中,利用数据库表查询的优势,快速破解。当然现如今网络上出现解密MD5的网站也很多。如下图
而且最近的一次事件也再次说明MD5加密方式的不安全。
SHA1:通过hash散列的方式。当然这里说道的hash函数和我们在数据结构中学到的hash函数还是有着区别的。它对长度小于264的输入,产生长度为160bit的散列值,它的抗穷性更好。
这里给大家介绍一种SHA1的扩展版(PBKDF2WithHmacSHA1),该算法采用加盐的方式。将密码和随机生成的盐序列合并,再采用hash函数方式,将其散列放置到数据库中。验证的时候需要将该用户的盐值和密码再次应用该算法计算出的hash字符串比较,相等就通过。这样即使hacker盗取了用户的密码,获取了hash字符串,由于无法知道用户的盐(而且是随机的),无法破解出用户的密码,也无法校验通过。加盐运算的方式如下。(当然存储的方式也有好多。可以将盐和生成的hash字符串合并存储到数据库中的字段里。类似于TCP/IP传输协议那样,在中间消息的两端加上盐值,盐的大小,密文的大小等。验证的时候再截取对应字块,比较校验即可。也可以分开存储,存储在不同的表中,达到安全的要求)。
通过加盐的方式
hash("hello")=2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hello" + "QxLUF1bgIAdeQX") =9e209040c863f84a31e719795b2577523954739fe5ed3b58a75cff2127075ed1
hash("hello" + "bv5PehSMfV11Cd") =d1d3ec2e6f20fd420d50e2642992841d8338a314b8ea157c9e18477aaef226ab
hash("hello" + "YYLmfY6IehjZMQ") =a49670c3c18b9e079b9cfaf51634f563dc8ae3070db2c4a8544305df1b60f007
以下变量是可以随意调整:
public static final int SALT_BYTE_SIZE = 24;//盐的大小
public static final int HASH_BYTE_SIZE = 24;//密文大小
public static final int PBKDF2_ITERATIONS = 10; //迭代计算总数
public static final int ITERATION_INDEX = 0;//迭代计数
生成的密文可以是这样:迭代次数:盐:hash值。
网上也有人说我可以将几种加密算法进行组合,先MD5加密,在SHA1加密等,虽然这种方式加大了破解的难度,但是无形中也增加验证的复杂度,带来的时间消耗也是可观的。因此我推荐这种采用加随机盐的方式,无论在抗破解或者验证方面,效果都是很好。感兴趣的朋友可以去网站上搜下。
二、人为因素
人为因素主要想说的是用户在无法保证密码存储安全性的时候,采用的主动出击方式将密码的安全性提高。而且尽量在电商网站上用的账户密码尽可能的不相同。防止被用来“撞库”。比如下方的密码设置就很有个性
恰逢最近诗词大会很火,我们是否也可以找上几句自己喜欢的歌词作为密码设置呢?同时设置密码的时候一定要多包含特殊字符,这样对用破解来说,难度无异于指数上升。而且还要经常留心网络上发生的账户泄漏大事件,如果自己有账户在上面,建议立刻修改,并将相关的账户密码改一下。
这是我通过朋友这件事得来的一点生活感悟。若有缺失和错误还请批评指正。