网络身份安全中的数据策略问题
文 / 江海客
当摩尔定律成为灾难
讲到破解对抗问题,要从攻防两方面所拥有的资源说起。之前我们基于一台普通的戴尔笔记本进行了一个小测试:在笔记本里装了一个虚拟机进行相应的Hash次数计算,发现这么普通设备里的虚拟系统,大概每秒钟可以完成50万次以上的标准MD5散列计算,这个结果得益于摩尔定律。我们要注意,这既是散列计算的速度,也是破解所需的数据资源生成的速度。这样的计算速度不仅为我们所拥有,也为神秘河对岸的攻击者所拥有,而且他们的有可能比我们更多。
首先,当前的云资源非常廉价,且都有开放式的计算服务可以借助。据我们所知,在很早以前俄罗斯的破解组织就可以使用俄罗斯科学院的大型机来进行相应的计算。其次,不容忽视的就是GPU的快速普及,对于生成彩虹表所需的配套数据,这可谓个人超算。GPU刚推出不久,就可以达到非常强大的能力:基于8台插有GPU加速卡的机器,在一些适合并发处理的计算中,可以模拟大约400台左右的标准x86节点的运行。这同样是攻击者非常容易获得,且便于他们之间相互分工的一种计算资源。另外攻击者拥有既有计算能力又有节点能力的资源—僵尸网络,它们有的数以万计、十万计,同时他们也进行节点的互动和买卖。这种僵尸网络不但可以承担一定的计算任务,而且可作为可控终端来使用,进行大量基于不同IP地址的所谓探测、撞号,甚至攻击等,还可以尝试控制当前网站流行采用的水印码。很多网站的水印码都会很快被攻击者找到相应的OCR SDK破解,并被分发到所有僵尸网络上。
基于目前的防护条件,网站想做到不被脱库是非常困难的,必须基于数据可能被窃取的前提来考虑整个安全策略,让被拖到的数据库对攻击者来说分析代价很大。
同时,我们也应该注意攻击者手中已经或可能掌握的明文口令资源,应该说这是具有较高价值的口令资源。比如在2002年底,陆续发现一些基于RPC口令猜测的蠕虫,并研究其密码档。那些口令猜测更多还是基于攻击者的经验,而当前的攻击者手中拥有的最优势资源是大量已泄露的口令。其中比较有代表性的是2011年上半年发生的索尼事件,约有超过一亿用户身份泄露,其中就有大量的明文密码,后来的世嘉,约130万用户,连花旗银行都有20万用户信息被泄露。虽然不包括口令等敏感信息,但也带有其他有效的用户信息。这样大量的明文资源为攻击者实现高速碰撞提供了帮助。
我们再来看一下计算资源,包括这些海量明文口令是通过哪些方式被利用的,这里就涉及到了目前已经为公众所知的彩虹表。当前整个基于彩虹表技术制作的大量查询资源,已达到少则几个GB,动辄几十个TB的规模。攻击者可以提供标准的Hash算法、一些场景中固定盐值的Hash算法,还有一些密钥固定的对称算法,完全都可以在这些资源中获得相应的查询。所以说本次事件不是一个简单的是否加密Hash,是否做了MD5的问题,而是在具备上述这些资源的前提下,使用标准的单向算法加密的结果实际上比明文好不了多少,根据我们的测试其被快速破解率可能在50%。所以说,使网站相应的加密策略达成到一定强度必须经过推敲,而且比较困难。
密文攻击方法及应对分析
基于目前的防护条件,网站想做到不被脱库是非常困难的,必须基于数据可能被窃取的前提来考虑整个安全策略,让被拖到的数据库对攻击者来说分析代价很大,这样攻击者可能就会放弃。那么就需要看看攻击者会对获得的数据做什么。
攻击者获取数据的方法很多,有的是自己拿到数据,有的是他人分享。很多时候,他们连同网站的整个代码一同拿到,这种情况很多,因为很多漏洞本身就是网站应用上的漏洞,而不是数据库上的漏洞。基于这个前提,我们必须了解,如果拿到的信息加密了的话,可能会遭到哪些威胁。首先要注意一点,为什么我们一再强调所谓“一用户一盐”这个问题,“一用户一盐”要达到的目的就是即使不同用户在同一个网站上使用了相同的口令,所保存的结果也不相同,因为如果相同的口令被单独保存且结果相同,就会遭到统计攻击。
这就意味着,在假定攻击者没有拿到源码和相应算法的情况下,他只需要少量尝试破解,就可以得出大量密码,从而使大约5%~15%用户密码被破解。注意,我们说的还是在没有拿到网站代码的加密方法的基础上,所以我们认为能够抵御统计分析和高频碰撞是作为整个后端加密系统的基础条件。同时,也要想到当攻击者拿到了相应的算法,包括拿到网站程序时,不管网站管理者做了什么样的修改,整个网站的算法已经公开。由目前整个网站的安全机制所限,原则上很难找到一个可以安全存放密钥的地方,也就是说我们所面临的最不利的条件是算法、密钥、密文完全遗失。在这种情况下,如果仅靠单向函数本身的特性很难完成,因为实际上在攻击者拿到一个仅对口令保存的密文之后,如果网站没有做到“一用户一盐”,实际上攻击者并不是基于生成一个穷举式的大表来查询的,而是基于网站所使用的相同的程序算法。他可能完全不理解网站的算法,但也完全能够调用网站加密的部分,首先把高频口令加工一部分,碰撞一次,比如Top 100,就有可能碰撞出20%的用户,之后完全可以基于上述的,以非常惊人的速度来实现对现有手中约千万级的已知明文口令,依托网站的算法生成密文完成碰撞。
由于网站不能做到不同用户相同密码的加密结果不同,所以这些用户都是通过一次碰撞出来的,碰撞时间相当短,而且这种碰撞我们还没有考虑到GPU加速的情况。基于这些我们可以评估一些错误的实现,它们包括:
- 单独使用标准Hash算法;
- 联合使用Hash;
- 使用非单向算法;
- 加一粒盐(SALT);
- 自己设计算法。
基于以上种种情况,经过研判,我们基本的思想是“一用户一盐”。
要做到其中的差异化,如下两点比较重要。第一、怎么做到“一用户一盐”,这个盐如何生成,如何取得对应关系呢?其实就是为每个用户基于随机数生成一个盐值,这个随机数基于时间,然后建立一个盐表,比如和UID是对应的。第二、一定不要在整个Hash计算中单独加密密码,要把个性化量加进来,比如说用户名。我们最近与一些同行交流经验,他们有的用了比较多的个性化量,比如注册时间、UID等。但是不是加得越多越安全呢?从数学意义上讲,在网站代码库被人获得的情况下,意义并不是特别大;但从分析意义上,它确实增加了分析者的成本。
在这种情况下,实际上并不能避免碰撞,能做到的是避免一次密文碰撞出所有结果,因为网站采用了“一用户一盐”的密码保存策略,包括个性化量,攻击者必须拿出整个常用的高频率码,基于网站当前用户的个性化量和盐,为这个用户生成一个加密结果,再和已有的加密结果比对。
如果网站把相关的思路,与禁止或者提醒用户避免使用高频密码相结合,甚至自身内嵌一个在线查询,不仅禁止使用高频密码,只要泄露过的密码都建议用户慎用,那么两个策略组合就会产生良好的反破解效果。
图1 密码保存策略
图1所示的APM中还有一个保存原始密码的功能,因为可能有些网站不希望重置密码,而是真的为用户找回密码,所以我们还是利用RSA给他封装了找回密码的应用。但我们讲了在当前的安全场景下并不具备单独保存密钥的安全可靠性,所以我们坚决提醒网站开发者,如果没有绝对必要的理由,要坚决慎用非单向方式来保存密码。
这里我们有一件最失落的事情,就是解决不了一号通的问题,有些用户在所有网站都用相同的密码和ID。此时攻击者在最开始时没有必要做高频或者海量碰撞,他只需要把现有的用户名和口令对应关系,依托当前的网站的设置,取到相应的个性化量,比如UID和注册时间,然后算一遍,直接碰撞出来。一号通的碰撞是比较难避免的。我们建议的另外一个方案就是不保存用户ID,但网站要知道这个人谁,不保存用户ID怎么显示呢?那么用户要设置一个昵称,可以建议昵称不允许和用户名相同,这样就增加了攻击者一定的复杂度,比如还需要用其他信息进行关联。但无论如何我们认为从前台机理上看,比如一号通的用户是要允许登录的,而这种情况在后台是我们无法解决的一个问题。
拒绝伪安全
我的同事张栗伟提出任何用于Web/DB场景的登录策略设计必须以下列因素的必然性为前提:
- 算法必然是公开的;
- Hash必然是飞快的;
- 彩虹表必然是只受存储制约的。
这也就是说攻击者是锐不可当的,但仍然可以采用以下的方式:第一个是口令规避,来增大攻击者加工的整个空间,我们也提供了一个云的查询方式,可以让网站封装在里面,用它来规避已泄露密码;第二个是可以考虑微软采用的动态均衡策略,当一个密码达到一定比率时就不允许再用了,这样就会使空间均衡,但这就有一个弱点,就是密码是要单独保存的,如果这个统计文件被拿到了,这也是灾难性的。同时我们最近也在尝试寻找是否有适用于Web/DB场景的加密硬件,由于整个加密参数的接口是不可以通过PCI槽来读写的,这样就能够从逻辑上无法获取加密参数,以体现保存问题。这里也有一定的问题:第一个是我们必须假定登录是一个常见操作,所以它应该具有一定的加速能力;第二个是当前很多网站是基于虚拟机的,所以这个加密卡必须支持虚拟机里面的系统。
当然还建议从运维策略进行调整,我们认为这里问题特别大的是包括网银和柜台交易有关的系统,虽然加了数字认证保护,但为了兼容它的柜台系统使用这种四位、六位或八位的数字密码,这里我认为它基于网络系统和柜台系统应该口令分支,网络系统可以输入长口令,在网络系统上无法获取它的柜台口令。同时我们在相关文章中也建议既然僵尸网络可以到网站注册垃圾用户,网站也可以自己注册,如果每有一个合法用户,网站运维者自己就注册10个假用户的话,攻击者很难把其中的合法用户挑出来,且对他的时间迟滞有一定的意义。同时网站可以在这些用户的存储密码值的地方放一些误导型算法,攻击者如果用这些Hash和常用口令碰撞,即使碰撞出来,也无法登录;而这种用户一旦用密码登录了网站就知道被脱库了,而攻击者发现无法登录,就会不再登了,这当然要看攻击者的耐心,或者攻击者会发现的情况,但这样的扰动因素有可能比本身在加密上的策略更有效。