祁鑫+++魏美荣+++蒋文保
【 摘 要 】 随着信息技术的快速发展与渗透,数据库应用越来越广泛。但伴随着近期CSDN、如家、汉庭甚至小米论坛所涉及的数据泄露事件,也表明了数据库存储的安全性问题日显突出。论文首先介绍了数据库存储安全的现状,区分了MD5的碰撞性在算法与在应用上的根本区别。然后,指出了传统MD5哈希算法与加盐哈希算法在某些应用场景下的误区,总结了安全的加盐哈希算法应用。最后,通过PBKDF2迭代算法对加盐哈希算法应用流程进行优化,利用Python编程还原哈希过程,并通过测试验证了该种慢速哈希算法的应用,可以使利用高性能硬件进行字典或者暴力破解的速度慢到没有实用价值。
【 关键词 】 数据库; 安全; 哈希算法; SHA256;PBKDF2
Security Analysis and Comparison of Password Encryption Algorithms
Qi Xin Wei Mei-rong Jiang Wen-bao
(Beijing Information Science and Technology University Beijing 100192)
【 Abstract 】 With the rapid development of information technology, Application database are more widely. But recent such as CSDN, even millet forum, home Hanting involved data leakage problems, it showed a significant outstanding safety issues with date database storage. This paper describes the status of the database storage security and distinction between the MD5 collision of fundamental differences in the algorithms and the application. Then, noting the traditional salted MD5 hash algorithm and hash algorithm errors in certain scenarios, summarized the safety salted hash algorithm used. Finally, improving the salt hash function by using PBKDF2 to iterative algorithm and using python programming to restore thehash process and validation this kind of slow hash algorithm applications can make the hash function very slow, so that even with a fast custom hardware, dictionary and brute-force attacks are too slow to be worthwhile.
【 Keywords 】 database; security; hah algorithm; sha256; pbkdf2
1 引言
随着计算机和网络的迅速发展,数据库应用越来越广泛。信息加密及用户认证机制对于用户数据的保护更显得至关重要。国外的学者Piyush Gupta(2014)从密钥、程序块、循环等方面对比了SHA与MD5算法[1]。国内研究人员对传统用户口令认证加密算法进行了研究。其中,刘洪民(2014.5)在“MD5算法在用户口令认证中的应用”中提出了通过加密过程变换、局部修改方法以保证MD5算法在应用中的安全性[2]。赵光亮(2015年)在“基于MD5 算法安全性研究发展及分析”中提出了通过加盐、多次加密等方法提高传统MD5算法安全性[3]。
本文通过对多种口令加密算法的安全性进行分析和对比后,发现传统MD5、SHA等哈希算法甚至改进的加盐哈希算法在某种程度上并不能满足口令加密在应用上的安全性需求。同时分析得出了慢速哈希算法在应用上可以较好的防止暴力破解攻击并利用python编程通过PBKDF2算法进行迭代改进了加盐哈希函数,最后通过测试验证了该种哈希机制在一定程度上可以解决目前传统哈希算法及部分加盐哈希算法所存在的问题。
2 安全加盐哈希算法分析
2.1 传统加盐哈希算法的误区
在传统的数据库密码存储过程中,很多服务商也会对密码加盐后进行哈希再存储,但有时即使这样还是出现了轻易被黑客的破解的情况,原因是对盐的使用存在的几个误区。
误区1:单一盐的使用
在每一个密码hash里使用相同的盐会使这种防御方法失效,因为相同的密码hash两次得到的结果还是相同的。攻击者就可以进行字典和暴力攻击,而他们只需要在对字典中每一个密码进行hash之前加上这个固定的盐就可以实现快速破解哈希摘要了。
误区2:使用长度较短的盐
当盐的位数较短的话,攻击者可以预先制作针对所有可能的盐的查询表。比如,3位ASCII字符的盐,一共只有95^3=857,375种可能性。看起来数量很多。假如每一个盐制作一个1MB的包含常见密码的查询表,857,375个盐才是837GB,而现在一个1TB的硬盘成本只有几百块而已。[4]黑客可以将彩虹表存储在大存容量盘中对密码进行暴力破解。
2.2 基于伪随机数生成器的加盐哈希算法
在相对安全的加盐算法中,每次用户在进行账号注册、密码更改等行为时都生成新的随机盐添加到用户的密码值中,再对其进行哈希。通过对用户注册密码加盐哈希并对其登录进行验证的流程如图1所示。
从图1中我们可以看到,流程的关键点在于随机盐的生成,若黑客可以猜测出进行哈希的盐,那么就可以通过彩虹表或反向查表等方式快速对哈希结果进行碰撞尝试,下面我们就来分析一下如何生成一个可靠安全的随机盐。
这里盐的生成,我们需要使用密码学上可靠安全的伪随机数生成器(Cryptographically Secure Pseudo-Random Number Generator,CSPRNG)来生成。本文利用Python编程语言分别编写了单纯sha1哈希算法与通过os.urandom模块进行加盐sha1哈希算法的两个应用,并对存储密码的同一文本进行哈希,得到结果如图2所示。可以从单纯进行sha1哈希的密文输出中看出,对同一字符串进行哈希得到的结果相同,那么黑客就可以通过排列查到一个用户数据库中重复率最高的密文,而这个密文对应的密码就很有可以是用户设置的弱密码,从而通过查询彩虹表或反向查询较容易地得出这个密码的原文。
从图2针对同一文本的加盐哈希值的输出结果中,可以看到加入随机盐后(这里使用的CSPRNG是Python中的os.urandom模块)对同一明文的进行哈希的结果却完全不同,这样黑客既无法找出密文的重复值也无法猜测出盐的值,从而大幅增加了攻击成本。
3 基于PBKDF2的慢速哈希算法分析
如2.2中所述,算法中加盐的步骤既可以应用在原始密码后,即
sha1($password.$salt)
也可以先将原始密码进行哈希对其结果加盐再进行第二次哈希,即
sha1(sha1($password).$salt
以上二者究其根本并无太大差异,并且通过安全的随机盐设置可以达到抵御大部分黑客使用彩虹表猜测及通过个人计算机进行暴力破解的威胁。但近一步假设,攻击者利用成本巨大的超级计算机群进行暴力猜解的话,那该算法被破解也将并非难事。因此,可以再如上算法的基础上近一步改进,减缓哈希的计算速度,再次提高破解成本,如此可以利用BCrypt或PBKDF2算法。该类算法的特点均为采用一种称为key扩展(key stretching)的技术。
这是一种基于迭代复杂度保证密码安全的加密方法。在进行加密之前,本文依旧用了os.urandom函数作为随机串生成器。
下面就是算法的执行过程,对于一个明文,算法将其与随机串连接后送入基础加密算法,得到一个加密串,再将加密结果与随机串连接,送入基础加密算法……如此迭代执行至达到预设的迭代次数为止。其中,迭代次数C决定了伪随机函数生成一个主密钥所需的迭代次数。这个值决定了输入密码的密钥生成时间,在用户可以接受这个时间长度下,迭代次数设置的越大越安全。对于普通用户而言,迭代次数建议至少为1000次。而对于一些极其重要的密码或者对于一些计算能力强大的系统,迭代次数设置为10,000,000次比较合适。其中,该算法中输入、参数、输出的对应值如表1-3所示。
算法如下所示。
If (kLen > (232-1) * hLen)
Return Error;
len = [kLen / hLen];
r = kLen - (len - 1) * hLen ;
For i = 1 to len
Ti = 0;
U0 = S || Int (i);
For j=1 to C
Uj = HMAC(P, Uj-1 )
Ti = Ti ?茌Uj
Return MK = T1 || T2 ||...|| Tlen<0…r-1>
其中,最后一次的加密结果就是算法的输出了。在验证的时候,将明文和存储的随机串重复上述加密过程,比对加密结果。其加盐哈希算法流程图如图3所示。
本文在安全加盐哈希算法的基础上改进了哈希函数,算法的设计思路是通过一种大量消耗CPU资源的hash函数让哈希过程变得非常缓慢,使得利用计算机群进行字典或者暴力猜解的速度也慢到没有实用价值。其中的安全变量或者迭代次数作为参数,而这个参数决定了哈希过程的速度是快是慢。通过参考美国国家标准,本文利用Python编写的基于PBKDF2的哈希算法。最后的哈希结果由base64加密输出,如图4所示。
可以看出使用PBKDF2哈希算法并将迭代次数设置为10000次后,计算13条密码的时间已经增加至将近2s,其相较普通的SHA1加盐哈希算法,计算时间得到大幅增加,这就意味着黑客在进行暴力破解时所花费的时间成本将会大到难以测量。为了直观的对比两种哈希算法的哈希时间,本文利用两种算法分别哈希一定数量的密码值。如表4所示,分别测试500、1000、5000、10000、20000个密码数据并记录所需的哈希时间,单位秒。
通过定量分析,将数据量化成可视化图表,这里仅举SHA512、PBKDF2(迭代1000次)、PBKDF2(迭代10000次)三种算法的测试结果为例,如图5所示。可以直观看到PBKDF2算法通过迭代大大增加了哈希时间,将迭代次数设置为10000次时,哈希20000个密码值时所用时间为2234秒,相比之下普通哈希算法所需时间还不到1秒。
根据上述结果大致推算,利用PBKDF2哈希算法,假设黑客在破解1000万个密码所花费的时间大约增加到了至少约25.3天,这可以以令黑客望而却步,也在极大程度上增加了黑客利用暴力破解或字典攻击所花费的时间成本。与此同时,每个密码仍使用不足1秒的时间进行加密,所以不会对用户体验产生什么影响。但由于用户密码存储的数据哈希主要用于Web应用中使用Key扩展hash函数,考虑到有大量的计算资源用来处理用户认证请求。在使用Key扩展的哈希函数,迭代次数的设置还是应该结合自己服务器的计算能力和预计每秒需要处理的认证请求次数进行参考。
4 结束语
本文针对数据库存储安全性现状与哈希算法进行了探讨和研究,明确了MD5的碰撞性在算法上与在应用上的实质性区别,并指出了传统哈希算法与加盐哈希算法在某些应用场景下的误区,总结了安全的加盐哈希算法应用,并利用Python编程还原哈希过程且对其进行验证。近一步,在上述安全加盐哈希算法的基础上改进了哈希函数,利用PBKDF2算法进行迭代计算,使得哈希过程变得非常缓慢,同样利用Python编程还原哈希过程且进行对其验证,并说明了该机制的实施可以使得利用计算机群进行字典或者暴力猜解的速度也慢到没有实用价值。
参考文献
[1] Piyush Gupta et al, A Comparative Analysis of SHA and MD5 Algorithm, IJCSIT(4492-4495)Vol.5 (3), 2014.
[2] 刘洪民,印帮辉.MD5算法在用户口令认证中的应用[J].网络安全技术与应用,2014(05).
[3] 赵光亮,韦雅文.基于MD5算法安全性研究发展及分析[J].福建电脑.2015(02).
[4] NIST Special Publication 800-132, Recommendation for Password-Based Key Derivation.
基金项目:
国家自然科学基金资助项目[61540020]。
作者简介:
祁鑫 (1991-),男,北京人,北京信息科技大学,在读研究生;主要研究方向和关注领域:信息安全。
魏美荣(1992-),女,北京人,北京信息科技大学,在读研究生;主要研究方向和关注领域:信息安全。
蒋文保(1969-),男,湖南人,毕业于清华大学,博士后,北京信息科技大学信息管理学院副院长,信息系统研究所副所长,教授,硕士生导师;主要研究方向和关注领域:网络与信息安全领域的科学研究、产品开发、教学和管理。