给自己扫盲——文件完整性校验

给自己扫盲——文件完整性校验


一直都在接触 md5 之类的东东,今天想起来深入了解一下,来弥补对这些加密算法常识上的缺失。

嘛,文章还在写。本文旨在给我自己扫盲🙆‍~这涉及密码学的很多相关概念。

什么是文件校验?

文件校验 就是 使用算法验证计算机文件完整性的过程。

你可以通过逐位(bit)比较两个文件来完成,但这需要同一文件的两个副本,并且可能会错过两个文件中可能出现的系统性损坏。

更流行的方法是还存储文件的校验和(散列),也称为消息摘要,以供稍后比较。

文件完整性验证

文件可能会被各种方式破坏:存储介质故障,传输错误,复制或移动时写入错误,软件错误等。

基于散列的验证通过将文件的散列值与先前计算的值进行比较来确保文件未被破坏。如果这些值匹配,则假定文件未修改。由于散列函数的性质,散列冲突可能导致误报,但是随机损坏,碰撞的可能性通常可以忽略不计。

文件真实性验证

CRC校验和不能用于验证文件的真实性,因为CRC32不是抗冲突的哈希函数 - 即使哈希和文件未被篡改,攻击者用相同的CRC摘要替换文件在计算上也是微不足道的。作为原始文件,意味着CRC比较未检测到文件中的恶意更改。

一些概念

密码散列函数(Cryptographic hash function)

是散列函数的一种。它是一种单向加密函数算法,从明文到密文不可逆的映射,也就是说只有加密过程,不能逆向出原文。

这种散列函数的输入数据,通常被称为消息(message),而它的输出结果,经常被称为消息摘要(message digest)或摘要(digest)。

在信息安全中,有许多重要的应用,都使用了密码散列函数来实现,例如数字签名消息认证码

一个理想的密码散列函数应该有四个主要的特性:

  • 对于任何一个给定的消息,它都很容易就能运算出散列数值。
  • 难以由一个已知的散列数值,去推算出原始的消息。
  • 在不更动散列数值的前提下,修改消息内容是不可行的。
  • 对于两个不同的消息,它不能给与相同的散列数值。

一些重要的应用:

  1. 保证数据的完整性
  2. 单向数据加密
  3. 数字签名

对散列函数的攻击是不可避免的,所以在设计算法函数的意义就在于让它的破解在计算上不可行。这里的计算上不可行大概就是指用现有的设备理论上在多少年时间内都不可破解之。碰撞攻击不可避免听上去根本就不安全嘛!但没关系,评价散列函数的有效方法就是看一个攻击者找到一对产生碰撞的字符串所花的代价有多高。

碰撞阻力是加密散列函数的一个属性:如果很难找到散列到同一输出的两个输入,则散列函数H是抗冲突的。碰撞阻力并不意味着不存在碰撞,只是他们很难找到。

碰撞攻击(Collision attack)

所谓哈希(hash),就是将不同的输入映射成独一无二的、固定长度的值(又称”哈希值”)。

如果存在一种相对“廉价”的方法,用不同的消息找到两个相同的摘要,则称之为哈希碰撞(collision)

防止哈希碰撞的最有效方法,就是扩大摘要长度(即哈希值的取值空间)。

哈希碰撞的概率取决于两个因素(假设哈希函数是可靠的,每个值的生成概率都相同):

  • 取值空间的大小(即哈希值的长度)

  • 整个生命周期中,哈希值的计算次数

目前散列函数的攻击方法

  1. 第一类称为穷举攻击(或暴力攻击)

    它能对任何类型的散列函数进行攻击。

    这里涉及生日攻击(birthday attack),一种利用哈希空间不足够大,而制造碰撞的攻击方法。为了限制本文篇幅,则不再引申。

    如果存在比这种暴力攻击更简单的方法,则通常将其视为散列函数中的缺陷

  2. 第二类称为密码分析法

    这类攻击方法依赖于对散列函数的结构和代数性质分析,采用针对散列函数弱性质的方法进行攻击。这类攻击方法有中间相遇攻击、差分分析等。

原像攻击(Preimage attack)

在加密中, 对加密散列函数的原像攻击指试图找到具有特定散列值的消息。加密哈希函数应该抵制对其原像的攻击。

在攻击的情况下,有两种类型的原像抗性

  • 第一原像抗性(preimage resistance):对于基本上所有预先指定的输出,找到任何哈希到该输出的输入在计算上是不可行的,即,给定 y​,很难找到 x​ 使得 h(x)= y​。
  • 第二原像抗性(second preimage resistance):找到任何与指定输入具有相同输出的第二输入在计算上是不可行的,即给定 x,很难找到第二个原像 x’(x’≠x),使得 h(x)= h(x’)。

再复习一遍 抗冲突性(Collision resistance),在计算上极其难以找到散列到相同输出的任何两个不同的输入xx ‘,使得hx)= hx ‘)。

常见校验算法

俺针对几种常见算法总结并画了张图。👇

CRC-32

MD5

MD5由国际著名密码学家图灵奖获得者兼公钥加密算法RSA的创始人Rivest设计。

当前,MD5算法因其普遍、稳定、快速的特点,仍广泛应用于普通数据的错误检查领域。例如在一些BitTorrent下载中,软件将通过计算MD5检验下载到的文件片段的完整性。

实现原理

填充:将输入信息进行512求余分组,若不等于448,那么进行填充 1 和0,一个1 N个0。最后的数据就为N*512+448。
记录信息长度:将得到的信息用64位存储填充之前的信息长度,这样448+64=512,总信息为N+1个512。

以四个常数ABCD与每组512位进行函数运算,最后输出的结果就是4组32位的常数。拼接得到MD5码。

缺陷
  • MD5的安全性:将用户的密码直接MD5后存储在数据库是不安全的。第一,用户普遍习惯用容易记忆的密码,生日,手机号等,黑客容易破译此类密码。这也是加盐值的一个原因。第二,直接MD5存入数据库,若数据库被破解,通过MD5反查会查到密码,需要随机盐值的配合。
  • md5绕过(Hash比较缺陷):在PHP中,由于0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,开头是0e的md5字符串都会被当成0。
  • 很容易遭到rainbow table攻击。

SHA-1

SHA-1是由美国专门制定密码算法的标准机构——美国国家标准技术研究院(NIST)与美国国家安全局(NSA)设计。

与MD5比较

因为二者均由MD4导出,SHA-1和MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

  • 对强行攻击的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是 $$2^{128}$$ 数量级的操作,而对SHA-1则是 $$2^{160}$$ 数量级的操作。这样,SHA-1对强行攻击有更大的强度。
  • 对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。
  • 速度:在相同的硬件上,SHA-1的运行速度比MD5慢。

早在2005年中国山东大学的教授王小云就实现了快于暴力破解的攻击技术。2005年的攻击能够在2的69次方计算中找到碰撞,或者说是暴力破解的2000倍,如密码学大师施耐尔所言“远超当前技术的能力”。

此次CWI和谷歌的方法,则“超过暴力破解的10万倍。”因次被称为入侵SHA-1加密算法数字签名的“首次可行性技术”。

“暴力破解需要1200万年的GPU计算时间,因此是不实际的。而SHAttered攻击要快上10万倍。攻击需要超过90亿亿次(没打错,是两个“亿” 9,223,372,036,854,775,808 )计算,等同于6500年的单个CPU时间和110年的单个GPU时间。”

SHA-2

  • SHA-224、SHA-256、SHA-384,和SHA-512并称为SHA-2。

  • 新的散列函数并没有接受像SHA-1一样的公众密码社区做详细的检验,所以它们的密码安全性还不被大家广泛的信任。

  • 虽然至今尚未出现对SHA-2有效的攻击,它的算法跟SHA-1基本上仍然相似;因此有些人开始发展其他替代的散列算法。

SHA-3

  • SHA-3,之前名为Keccak算法,是一个加密杂凑算法。

  • SHA-3并不是要取代SHA-2,因为SHA-2目前并没有出现明显的弱点。

  • 由于对MD5出现成功的破解,以及对SHA-0和SHA-1出现理论上破解的方法,NIST感觉需要一个与之前算法不同的,可替换的加密杂凑算法,也就是现在的SHA-3。

附录

对散列函数碰撞攻击的破解现状

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×