貌似大年夜大都渗入师都很少测试暗码学方面的缝隙。我一向都对暗码学很有欢愉爱好,因而决定研究web利用开辟者误用加密算法的环境,和若何操纵这些缝隙。
一月份的时辰,我研究了下对一些比较弱的Message Authentication codes(MACs)[译者注:关于MAC与hash的辨别拜见此链接],若何进行哈希长度扩大(hash length extension)报复打击。我发现一些很不错的论文和博文,谈到了这类报复打击编制。但是,针对哈希长度扩大报复打击的具体细节,却鲜有资料。在这篇文章中,我将会对此进行具体诠释。
Message Authentication Codes 101
Message authentication codes (MACs)是用于验证信息真实性的。最简单的MAC算法是如许的:办事器把key和message连接到一路,然后用摘要算法如MD5或SHA1取摘要。例如,假定有一个网站,在用户下载文件之前需验证下载权限。这个网站会用以下的算法产生一个关于文件名的MAC:
def create_mac(key, fileName)
return Digest::SHA1.hexdigest(key + fileName)
End
最终产生的URL会是如许:
http://example.com/download?file=report.pdf&mac=563162c9c71a17367d44c165b84b85ab59d036f9
当用户倡议要求要下载一个文件时,将会履行下面这个函数:
def verify_mac(key, fileName, userMac)
validMac = create_mac(key, filename)
if (validMac == userMac) do
initiateDownload()
else
displayError()
end
End
如许,只有当用户没有私行更改文件名时办事器才会履行initiateDownload()开端下载。实际上,这类生成MAC的编制,给报复打击者在文件名后添加自定义字串留下可乘之机。
Length Extension Attacks, The Simple
Explanation
哈希摘要算法,如MD5,SHA1, SHA2等,都是基于Merkle–Damgrd布局。这类算法有一个很成心思的标题问题:假定你知道message和MAC,只需再知道key的长度,虽然不知道key的值,也能在message后面添加信息并计较出响应MAC。
Example: message + padding +extension
继续用上面的例子,对文件下载的功能进行长度扩大报复打击:
http://example.com/download?file=
report.pdf%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%A8/../
../../../../../../etc/passwd&mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5
Length Extensions In Depth
为了理解这类报复打击编制,你必需先体味hash函数的内部道理。
How Hash Algorithms Work
哈希函数以区块为单位把持数据。好比说,MD5, SHA1, SHA256的区块长度是512 bits 。大年夜大都message的长度不会刚好可以被哈希函数的区块长度整除。如许一来,message就必需被填充(padding)至区块长度的整数倍。用前面文件下载的MAC的例子来讲,填充后的message是如许的(‘x'暗示key):
*********xxreport.pdf\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\xA8
在本例所用的SHA1算法中,哈希值由五组整数构成。一般我们看到的情势是把这五个整数转换为16进制然后连接到一路。运行算法时,初始值(又叫registers)被设置为这组数:67452301, EFCDAB89,
98BADCFE, 10325476, C3D2E1F0. 紧接着,填充message,再将其豆割为512bits的区块。算***流把持每个区块,进行一系列的计较并更新registers的值。一旦完成了这些运算,registers里的值就是最终的哈希值。
Calculating An Extension
计较扩大值得第一步是成立一个新的MAC。我们起首对待扩大的值:上例中的‘/../../../../../../../etc/passwd’进行哈希摘要。可是,在进行摘要之前,我们要把registers里的初始值设置为原始message的MAC。你可以将其想象为让SHA1函数从办事器上的函数运行结束的处所继续进行。
报复打击者的 MAC = SHA1(extension + padding) <- 笼盖registers初始值
这个报复打击有个前提,在传进办事器的哈希函数时,扩大值必需存在于伶仃的区块中。所以我们的第二步,就是计较出一个填充值使得 key + message + padding == 512 bits 的整数倍。在此例中,key是11个字符的长度。是以填充以后的message是如许的:
report.pdf\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA8
传送到办事器的填充及扩大以后的message和新的MAC:
http://example.com/download?file=report.pdf%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%A8/../../../../../../../etc/
passwd&mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5
办事器要进行摘要运算的被报复打击者窜悔改的message以下:
secret + message + padding to the next block +
extension + padding to the end of that block.
办事器算出的哈希值将是ee40aa8ec0cfafb7e2ec4de20943b673968857a5,正好与我们添加扩大字串并笼盖registers初始值所计较出来的一样。这是因为报复打击者的哈希计较过程,相当于从办事器计较过程的一半紧接着进行下往。
How To Run The Attack
为了简单,在这个例子中我流露了密钥长度是11位。在实际报复打击环境中,报复打击者没法获知密钥长度,需要对其长度进行猜想。
继续之前的例子,假定当MAC验证掉败时,这个存在缝隙的网站会返回一个弊端信息(HTTP response code 或response body中的弊端动静之类)。当验证成功,可是文件不存在时,也会返回一个弊端信息。假定这两个弊端信息是不一样的,报复打击者便可以计较不合的扩大值,每个对应着不合的密钥长度,然后别离发送给办事器。当办事器返回表白文件不存在的弊端信息时,即申明存在长度扩大报复打击,报复打击者可以随便计较新的扩大值以下载办事器上未经许可的敏感文件。
How To Defend Against This Attack
解决这个缝隙的编制是利用HMAC算法。该算法大年夜概来讲是如许 :MAC =
hash(key + hash(key + message)),而不是简单的对密钥连接message以后的值进行哈希摘要。
具体HMAC的工作道理有些复杂,但你可以有个大年夜概的体味。重点是,因为这类算法进行了两重摘要,密钥不再受本文中的长度扩大报复打击影响。HMAC最早是在1996年被颁发,以后几近被添加到每种编程说话的尺度函数库中。
Summary
虽然仍有一些疯狂的人类在写本身的加密算法,尽大年夜大都人已垂垂发现本身写加密算法不是甚么好主张。但是,不纯真的套用公开的加密算法也是有其意义的,前提是你可以或许准确的利用这些加密算法。除非你完全吃透你利用的加密算法的道理,并知道若何准确利用,不然仍是直接用那些颠末端专业级审查的高级算法库要安然些。