由拖库攻击谈口令字段的加密策略(数据库加密)

这些事件中最令业界瞠目的是RSA被入侵,这直接导致多家工业巨头遭遇连锁的攻击,很多安全企业本身也使用RSA的令牌。比RSA弱小很多的荷兰电子认证公司DigiNotar已经在被入侵后,宣告破产。

  就在2011年上半年,我们还是站在旁观者的立场讨论这些事情。但随即我们就遭遇了CSDN、多玩和天涯等等的数据泄露,其中最为敏感的,一方面是用户信息,另一个当然就是用户口令。由于身份实名、口令通用等情况影响,一时间人人自危。各个站点也陷在口水当中。

  但实际上根据推断,这些入侵都是一些过去时,也就是说这些库早就在地下流传。同时流出,也许就是一个集体性的心理效应。

  这种针对数据库记录的窃取,被一些攻击者称为“拖库“,于是有了一个自然而谐音的戏称“脱裤”。只是攻击者日趋不厚道,从前只是偷了人家的裤子,现在还要晾在大街上,并贴上布告说,“看,丫裤子上还有补丁呢”。

  如果拖库是很难避免的,那么采用合理的加密策略,让攻击者拿到库后的影响降低到更小就是必要的。

  明文存放口令的时代肯定是要结束了,但加密就安全么?

  那些错误的加密策略

  明文的密码固然是不能接受的,但错误的加密策略同样很糟糕。让我们看看下列情况。

  简单使用标准HASH

  我想起了一个90年代黑客笑话,有人进入一台UNIX主机,抓到了一个shadow文档,但破解不了。于是,他用自己的机器做了一个假的现场,故意留下这个shadow,最后看看别人用什么口令来试,最后再用这些口令与渗透原来的主机。遗憾的是,那时我们都把这个当成一个Joke,充其量回复一句“I服了you!“,而没有反思使用标准算法的问题。

  目前来看,在口令保存上,使用最为广泛的算法是标准MD5 HASH。但实际上,很长时间,我们都忽略了HASH设计的初衷并不是用来加密,而是用来验证。系统设计者是因为HASH算法具有不可逆的特点所以“借”用其保存密码的。但其不可逆的前提假设,是明文集合是无限大的。但放到口令并不一样,口令的长度是受限的,同时其可使用的字符也是受限的。我们可以把口令的总数看正一个事实上的有限集(很难想象有人用100个字符作为口令)。

  比如一个人的密码是“123456”,那么任何采用标准MD5加密的网站数据库中,其存放的都是这样一个MD5值:E10ADC3949BA59ABBE56E057F20F883E

  由于密文均相同,加之HASH算法是单向的,因此攻击者较早使用的方法就是“密文比对+高频统计“后生成密文字典来攻击,由于绝大多数网站和系统的加密实现,都是相同明文口令生成相同的密文,因此,那些有高频密文的用户就可能是使用高频明文口令的用户。攻击者一方面可以针对标准算法来制定高频明文的对应密文档来查询,另一方面,对于那些非标准算法,高频统计攻击的方法也非常常见。

  但查表攻击迅速压倒高频统计的原因,正是从2000年开始陆续有网站规模性明文口令泄漏事件开始的。在过去每一次明文的密码泄漏事件,攻击者都会把使用MD5、SHA1等常见HASH算法加工成的口令与那些采用HASH值来保存的库进行应对。

  随着超算资源的廉价、GPU的普及、存储能力的增长,一个不容忽视的威胁开始跃上桌面,那就是,这些巨大的HASH表已经不仅仅是基于泄漏的密码和常见字符串字典来制作,很多攻击者通过长期的分工协作,通过穷举的方式来制作一定位数以下的数字字母组合的口令串与多种算法加密结果的映射结果集,这些结果集从百GB到几十TB,这就是传说中的彩虹表。

  HASH的单向性优势在此已经只有理论意义,因为HASH的单向性是靠算法设计保证的,使用一个有限集来表示一个无限集,其必然是不可逆的。但攻击者是从查表来完成从HASH到口令明文的还原的。因此其算法的单向性也就失去了意义。

  联合使用HASH

  一些人误以为,HASH不够安全是因为HASH算法的强度问题,因此把MD5或者SHA1联合使用,其实这是毫无价值的(只是徒耗了存储资源)。如上面所说,HASH的不安全性在于大量口令与其HASH值的对应关系早已经被制作成彩虹表。只要你联合使用HASH的算法其中之一在彩虹表中,自然就可以查到了。

  同理,那种采用“MD5的头+SHA的尾“之类的,或者采用其他的混合两个值的方法,也一样是没有意义的。因为攻击者可以很容易的观察到这种组合方法的规律,经过拆解后继续按照查表法破解。

  自己设计算法

  我一向认为,既然我们不是一个密码学家,而是工程师、程序员,那么放着现成的好东西不用,自己开发加密算法是相当愚蠢的事情。我相信很多程序员都遇到过挖空心思想到了一个“新算法”,然后发现早在某篇20世纪80年代的数学论文里,早就提出了相关算法的情况。

  况且在开源时代,很多算法不仅被实现和发布了,而且还经历了长期的使用推敲。这些都是自己设计、自己实现无法比拟的。

  关于自主设计的算法的不安全性,有一个事情深达我脑海。记得我在证券系统工作时,由于刚刚接手收购来的营业部,需要把一个clipper编译的柜台系统进行迁移,但原来的开发商已经联系不到了,当时我们制定了两条路,一位高手李老师负责,进行数据破解,看看是否能还原明文,而我则负责破解算法,如果李老师那边走不通,则我需要解出算法,把000000~999999之间的数字全部加密,然后用密文做碰撞(那时证券都是柜台操作,没有网上炒股,密码都是柜台用数字键盘输入的)。

  由于原来的开发者加了一点花活,我这边还没有眉目,那边旁观李老师的工程师,已经发出了惊叹之声,我跑过去,只见李老师根据构造的几个密码的加密结果,在纸上汇出了长得非常像杨辉三角的东西。不到半个小时,李老师已经连解密程序一起做好了。

  上面故事的目的是说明,自己设计算法无论怎么自我感觉良好,看看美国官方遴选算法的PK过程大家就明白了,我们无法和全球数学家的智慧组合对抗。

  因此自己设计实现算法,并不是一个好主意。这其中也包括,在实现上会不会有类似输入超长字符串会溢出一类的Bug。

  单独使用对称算法

  在标准HASH安全破灭后,又看到有人呼吁用AES,其实这不是一个好建议。AES这些对称算法,都不具备单向性。网站被攻击的情况是复杂的,有的是只有数据库被拖,有的则整个环境沦陷。而后者AES密钥一旦被拿到,密码就会被还原出来,这比被查表还要坏。

  当然我们还看到一种把AES当HASH用的思想,就是只保留一部分的AES加密结果,只验证不还原。但其实这样的AES并不见得比HASH有优势。比如即使攻击者没有拿到密钥,也只拖了库,但攻击者自己在拖库之前注册了足够多的帐号,并使用大量不同的短口令。那么就拿到了一组短明文和对应密文。而此时密钥是完全有可能被分析出来的。

  而使用DES、AES一类的算法,还是使用标注HASH,还是自己设计算法,如果不解决不同用户相同口令密文相同的统计性缺陷,那么攻击者即使拿不到密钥,也都可以先把一些高频口令用于帐号注册,拖库后进行密文比对。就可以锁定大量的采用常见口令的用户。

  加“一粒盐”

  其实很多同仁都指出了哈希加盐法(HASH+SALT),是问题的解决之道,所谓加盐(SALT)其实很简单,就是在生成HASH时给予一个扰动,使HASH值与标准的HASH结果不同,这样就可以抗彩虹查表了。

  比如说,用户的密码是123456,加一个盐,也就是随机字符串“1cd73466fdc24040b5”,两者合到一起,计算MD5,得到的结果是6c9055e7cc9b1bd9b48475aaab59358e。通过这种操作,即便用户用的弱密码,也通过加盐,使实际计算哈希值的是一个长字符串,一定程度上防御了穷举攻击和彩虹表攻击。

  但从我们审计过的实现来看,很多人只加了“一粒盐”。也就是说,对同一个站点,不同用户使用同一个密码,其密文还是相同的。这就又回到了会遭遇高频统计攻击,预先注册攻击等问题。

  口令的安全策略

  在传统密码学家眼中只有一种加密是理想的,那就是“一次一密”,当然事实上这是不可能的。但如果我们套用这种词法,我们也可以说,口令安全策略的理想境界,我们可以称为单向、一人一密、一站一密。

  单向:标准HASH算法的价值尽管在这个场景下,已经被推倒,但其单向性的思想依然是正确的,口令只要是能还原的,就意味着攻击者也能做到这一点,从而失去了意义,因此使用单向算法是必须的。

  一人一密:同一个站点设置同样口令的不同用户,加密生成的密文内容并不相同。这样就能有效的应对结果碰撞和统计攻击。采用字典的攻击的方法基本是不收敛的。

  一站一密:仅仅保证一人一密是不够的,还要保证使用同样信息、同样口令去注册不同网站的用户,在不同站点的口令加密结果是不同的。鉴于有大量用户用同样的信息、同样的口令去注册不同网站,如果能做到这一点,流失出的库信息会进一步打折扣。而攻击者基本会放弃生成密文字典的尝试。

  实现这些说起来很简单,依然是HASH+SALT,关键在于每个站点要有不同的SALT,每个用户要有不同的盐。

  但如果攻击者不是只获得了库,而且也获得了相关的加密参数和密钥,我们就要看到攻击者依然可以自己通过相关参数和密钥调用算法,使用常见密码对每个用户生成一遍密文,然后是否有匹配。当然我们可以看到由于“每人一粒盐”的策略,攻击者所需要的计算代价已经变化了,如果过去只需要生成一次的话,那么假如使用100个常见的口令来做,那么只要口令没有碰撞到,对每个用户都要做100次加密操作。但这也是不容小觑的威胁。因为有太多用户喜欢使用那些常见口令。

  因此,设定一个密码禁用表,让用户避免使用常见口令,可以进一步让破解者付出更大的代价,从而最终导致计算资源不收敛而放弃,也可以是一个可以考虑的策略。但也需要提醒WEB开发者的是,这样会增大你的用户忘记口令的风险。

  另外,用户是否有把密码设置为123456的自由呢,我想只要不是国防、航天、涉密系统和有安全要求的企业环境,如果只是潜潜水、骂骂街,网站或许提醒用户就好,但也许并不需要做成强制策略。

  具体的实现

  了这么多,怎么来具体实现一站一密、一人一密的策略呢,2011年12月23号,我们想到与其空洞的说教算法原理和策略,不如提供一些非常直接的示例程序和文档。

  因此同事们写了一份名为Antiy Password Mixer(安天密码混合器)的开源代码,当然这没有什么技术含量,也不是“自有知识产权的国产算法”,有的只是对实现较好的流行开源算法包的示范性使用而已,目前的Python版本,也只有三百行代码,在其中封装了RSA和HASH+SALT使用,并给出了具体的在初始化、注册和认证时如何使用的范例文档。

  大家可以在这里找到这个东西:http://code.google.com/p/password-mixer/

  当然,就像我们惋惜很多应用开发者缺乏对安全的重视一样,其实我们并不懂应用开发,所以这些代码和文档对于应用开发者看来可能非常丑陋。尽管可能被鄙视,我们还是要打开门,证明安全团队并不保守。

  而同时,我们必须与应用走得更近,因为我们也在使用着这些自认为违反了某种安全原则的应用,却因为不是其开发者而无法改造它们。

  过去的10余年,中国的Web应用甩开安全而飞速狂奔,开发者们凭借自身的勤奋和冲击力奠定了现有的格局,但也因快速地奔跑遗落了一些东西,比如安全。也许现在是拾起这些弃物的时间了。

  中国的安全界则因保守、敏感和很多自身的原因,与应用的距离越拉越远,在我们还在幻想某些完美的安全图景时,发现我们已经望不到应用的脊背了。也许,在应用会回头等等我们的时候,就是我们加速前行、拾起应用所遗落的安全性,追送上去的时间了。

(0)

相关推荐

  • asp.net2.0如何加密数据库联接字符串

    asp.net2.0如何加密数据库联接字符串 在asp.net2.0中,发布网站时,加密web.config,这样可以有效保证数据库用户和密码安全,其步骤如下: 1.添加密钥 执行:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pc "hnlaw" -exp 其中"hnlaw"为密钥名称 2.添加web.config节点 在web.config的<configuration>&l

  • 加密你的Access数据库asp打开方法

    Secure Your Access Database How can you keep unwanted people from downloading your database simply by typing in the url? You can't, it is not possible. BUT you can secure it by adding a password to it. Below I will walk you through the steps needed t

  • ASP.NET web.config中 数据库连接字符串加密解密

    虽然不怎么新鲜,但相信还是有许多人不知道,好,不说废话,直接给方法:开始--->运行,输入cmd,接着输入以下内容 加密: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pef "connectionStrings" "你的Web项目路径" 解密: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -

  • 使用 Salt + Hash 将密码加密后再存储进数据库

    (一) 为什么要用哈希函数来加密密码 如果你需要保存密码(比如网站用户的密码),你要考虑如何保护这些密码数据,象下面那样直接将密码写入数据库中是极不安全的,因为任何可以打开数据库的人,都将可以直接看到这些密码. 解决的办法是将密码加密后再存储进数据库,比较常用的加密方法是使用哈希函数(Hash Function).哈希函数的具体定义,大家可以在网上或者相关书籍中查阅到,简单地说,它的特性如下: (1)原始密码经哈希函数计算后得到一个哈希值 (2)改变原始密码,哈希函数计算出的哈希值也会相应改变

  • 在asp.net中使用加密数据库联接字符串保证数据安全

    在我们发布网站时,加密web.config,这样可以有效保证数据库用户和密码安全,其步骤如下: 1.添加密钥 执行:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pc "hnlaw" -exp 其中"hnlaw"为密钥名称 2.添加web.config节点 在web.config的<configuration></configuration>之间添加: <con

  • 由拖库攻击谈口令字段的加密策略(数据库加密)

    这些事件中最令业界瞠目的是RSA被入侵,这直接导致多家工业巨头遭遇连锁的攻击,很多安全企业本身也使用RSA的令牌.比RSA弱小很多的荷兰电子认证公司DigiNotar已经在被入侵后,宣告破产. 就在2011年上半年,我们还是站在旁观者的立场讨论这些事情.但随即我们就遭遇了CSDN.多玩和天涯等等的数据泄露,其中最为敏感的,一方面是用户信息,另一个当然就是用户口令.由于身份实名.口令通用等情况影响,一时间人人自危.各个站点也陷在口水当中. 但实际上根据推断,这些入侵都是一些过去时,也就是说这些库早

  • 利用SQL注入漏洞拖库的方法

    想在本地测试的话,可以在此免积分下载:利用SQL注入漏洞拖库 同上一篇文章一样,我们需要创建数据表,并在表中出入几条数据以备测试之用. 在数据库中建立一张表: 复制代码 代码如下: CREATE TABLE `article` ( `articleid` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(100) CHARACTER SET utf8 NOT NULL DEFAULT '', `content` text CHARACTER SET

  • 浅谈C# 字段和属性

    一.浅谈访问修饰符 作用:设定访问权限,限制类中的成员(属性.方法等)可访问的范围,访问范围通常有,类的内部.类的外部. 最常用的类型:private(私有的,仅类的内部使用):public(公有的,没有访问限制) 注意:类的成员在定义的时候没有显示的写出访问修饰符,则默认是private.对应到字段和属性中,通常字段修饰为private,属性修饰为public. 二.字段的使用 1.关于字段 a.字段又称为:"成员变量",一般在类的内部做数据交互使用. b.字段命名规范:camel命

  • 浅谈python量化 双均线策略(金叉死叉)

    #小策略,策略逻辑是在金叉时候买进,死叉时候卖出,所谓金叉死叉是两条均线的交叉,当短期均线上穿长期均线为金叉,反之为死叉 #下面是策略代码及结构 # 导入函数库 from jqdata import * # 初始化函数 def initialize(context): # 设定沪深300作为基准 set_benchmark('000300.XSHG') # True为开启动态复权模式,使用真实价格交易 set_option('use_real_price', True) # 股票类交易手续费是:

  • 浅谈如何使用vb.net从数据库中提取数据

    1.设置从Model中的Sub Main 启动 2.程序结构 3.Model1 Imports System.Windows.Forms.Application Module Module1 Sub Main() 'form1 是测试多文档窗口 'Dim frm1 As New Form1() 'frm1.Show() Dim formStudentSysMain As New FormStudentSysMain() formStudentSysMain.Show() Do While Tru

  • 数据库加密字段进行模糊查询详解

    目录 需求 服务器端解密 数据库端解密 字符串分片 代价 密文长度较长 分片长度不能太短 可能有多余结果 需求 对于一些敏感字段,比如手机号码.身份证.地址.银行卡号等,我们在存放进数据库前,可能需要对其进行加密. 大部分情况下,我们只需要支持等值查询.但是如果需要支持模糊查询,那么整段内容整体加密就不具备这个能力. 下面是几种解决办法,场景是我们需要根据手机号码的前缀进行匹配. 服务器端解密 因为服务器肯定是具备解密密文的能力的,因此最简单的方式就是把整个表的密文字段数据拉下来,在服务器端进行

  • DDoS攻击的趋势与相关防御策略

    一.阻断服务(Denial of Service) 在探讨 DDoS 之前我们需要先对 DoS 有所了解,DoS泛指黑客试图妨碍正常使用者使用网络上的服务,例如剪断大楼的电话线路造成用户无法通话.而以网络来说,由于频宽.网络设备和服务器主机等处理的能力都有其限制,因此当黑客产生过量的网络封包使得设备处理不及,即可让正常的使用者无法正常使用该服务.例如黑客试图用大量封包攻击一般频宽相对小得多的拨接或 ADSL 使用者,则受害者就会发现他要连的网站连不上或是反应十分缓慢. DoS 攻击并非入侵主机也

  • 用SQL语句添加删除修改字段、一些表与字段的基本操作、数据库备份等

    用SQL语句添加删除修改字段 1.增加字段 alter table docdsp add dspcode char(200) 2.删除字段 ALTER TABLE table_NAME DROP COLUMN column_NAME 3.修改字段类型 ALTER TABLE table_name ALTER COLUMN column_name new_data_type 4.sp_rename 改名 更改当前数据库中用户创建对象(如表.列或用户定义数据类型)的名称. 语法 sp_rename

  • PHP以指定字段为索引返回数据库所取的数据数组

    很多情况下,我们从接触一个新的项目到开发完成,再回过头来仔细浏览一下自己写的代码,很多都是我们以前用熟练的代码.所以,在完成每个新项目的时 候,适当的做些项目总结.代码总结,或许你会在以后的项目中用得着,极有可能获得意外的收获,比如:代码优化,想到了更好.速度更快的实现方法等等. 牛逼的程序开发者有时候不在于代码量的多少,而是程序的代码简洁性.逻辑复杂但实现的方便性,这些才说明是否是一位好的程序员.我们不做日夜加班到深夜,拼代码量的程序员! 这篇和大家分享几个使用得PHP编程技巧,有些技巧是在看

  • 浅谈webpack 构建性能优化策略小结

    背景 如今前端工程化的概念早已经深入人心,选择一款合适的编译和资源管理工具已经成为了所有前端工程中的标配,而在诸多的构建工具中,webpack以其丰富的功能和灵活的配置而深受业内吹捧,逐步取代了grunt和gulp成为大多数前端工程实践中的首选,React,Vue,Angular等诸多知名项目也都相继选用其作为官方构建工具,极受业内追捧.但是,随者工程开发的复杂程度和代码规模不断地增加,webpack暴露出来的各种性能问题也愈发明显,极大的影响着开发过程中的体验. 问题归纳 历经了多个web项目

随机推荐