0X00 前言
最近到朋友那里薅了一本python全栈安全,但是当我打开书仔细翻阅了之后才发现这本python全栈安全和python安全没有一丢丢关系。于是抱着多学一点不吃亏的心态还是看了起来。
那这本python全栈安全和python安全没有一丢丢关系。那它都讲了什么啊?揭秘:我个人觉得讲的偏向于数据安全,与python相关的就是使用python的函数、库进行运算。
最近一直在整java代码审计,这些东西再不用用我怕忘了就!我结合自己的理解以及自己编的一个Yu9与黑客的小故事。和师傅们一块分享一下什么是数据完整形与数据身份加密。
在此之前,我们需要先了解一个概念,散列。
0X01 散列
1、什么是散列?
Hash(哈希),又称“散列”。散列(hash)英文原意是“混杂”、“拼凑”、“重新表述”的意思。
在某种程度上,散列是与排序相反的一种操作,排序是将集合中的元素按照某种方式比如首字母a、b、c...排列在一起,而散列通过计算哈希值,打破元素之间原有的关系,使集合中的元素按照散列函数的分类进行排列。
2、散列的发展史
早期散列函数
在计算机科学的早期阶段,最早的散列函数是非常简单的算法,例如,取数据的某个字节作为哈希值,或者对数据进行简单的运算(如求和、乘法等)得到哈希值。这些简单的散列函数通常无法提供良好的散列性能和安全性。
数字校验和
随着计算机网络的兴起,人们开始关注数据完整性的问题。校验和算法应运而生,用于验证数据在传输过程中是否发生了变化。
常见的校验和算法包括CRC(循环冗余校验)和校验和位的累加等。这些算法通过对数据进行散列运算和异或操作,生成一段固定长度的校验和,以便接收方验证数据的完整性。
哈希表
20世纪70年代,散列表成为一种常见的数据结构,被广泛应用于快速查找。散列表使用散列函数将关键字映射到数组的特定位置,以实现常数时间的查找、插入和删除操作。
密码学
在密码学中,散列函数被广泛应用于生成消息摘要,以用于数字签名和数据完整性验证。
例如,MD5是一种广泛使用的散列算法,它将任意长度的数据转换为128位的哈希值。然而,随着计算机计算能力的增强,MD5逐渐暴露出碰撞的安全问题,因此被SHA-1等更安全的散列算法取代。
安全散列算法
为了应对散列算法的安全性问题,人们开始研究和设计更安全的散列算法。SHA-2系列(如SHA-256)和SHA-3系列是最常见的安全散列算法。
这些算法在设计上更加复杂和安全,并且具备抗碰撞、抗预映射和抗区分攻击等特性。此外,还有一些新型的散列算法,如blake2和whirlpool等,它们在特定场景下具有更好的性能和安全性。
散列算法的应用扩展
随着计算机科学和信息安全的不断发展,散列算法的应用范围也不断扩展。散列算法被广泛应用于密码存储、数字证书、数据验证、文件指纹、随机数生成和密钥派生等领域,以提供数据的完整性、唯一性和安全性保障。同时,散列算法也为分布式系统、大数据处理和区块链等领域提供了基础支持。
3、碰撞
什么是碰撞?
在上文中我们提到了碰撞一词,接下来就详细讲讲什么是碰撞。
举个例子,通过例子来解释哈:
通常我们存储数据会使用到数组,在查找某个元素是否存在的过程中,就需要挨个循环比较。一旦存储的内容数量特别多,我们在查找时就需要大量时间。
在java中有hashCode()
函数,它就是一个哈希算法,它的输入是任意字符串,输出是固定的4字节int
整数。
例如:
"hello123".hashCode(); // 0x5e918d2
"hello456".hashCode(); // 0x7a9d88e8
"hello789".hashCode(); // 0xa0dbae2f
在存入数据时,通过
hashCode()
计算出一个hash值
来标记它的位置在查找数据时,先计算出他的位置,然后去那个位置查看是否存在就好了
但是hashCode()
输出是4字节整数,最多只有4294967296种输出,但输入的数据长度是不固定的,有无数种输入。所以,哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会出现相同的结果,这就是碰撞。
例如:
"AaAaAa".hashCode(); // 0x7460e8c0
"BBAaBB".hashCode(); // 0x7460e8c0
碰撞能不能避免?
答案是不能。哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。
碰撞不可怕,我们担心的不是碰撞,而是碰撞的概率,因为碰撞概率的高低关系到哈希算法的安全性。一个安全的哈希算法必须满足:
碰撞概率低;
不能猜测输出。
4、散列的特征
相同的输入一定得到相同的输出;
不同的输入大概率得到不同的输出。
5、选择加密散列函数
不安全的散列函数
MD5
SHA-1
MD5是一个过时的128位散列函数,是因为每一个原始密码都会生成一个对应的固定密码,也就是说一个字符串生成的MD5 值是永远不变的。 这样的话,虽然它是不可逆的,但可以被穷举。
SHA-1是一个过时的128位散列函数,SHA-1的碰撞攻击是在2005年被首次公开揭示,但随着时间的推移,攻击者的攻击方法和技术也在不断进步。2017Google研究人员宣布完成全球首例SHA-1哈希碰撞。从理论上说,SHA-1此刻起就不在安全!
安全的散列函数
SHA-2
SHA-3
BLAKE2
SHA-2是一组散列函数家族,包括SHA-224、SHA-256、SHA-384、SHA-512等。目前我们只需关注SHA-256即可。why?因为这将是我们目前碰多最多的加密散列,我们采用的每个系统都在使用它。我们部署应用程序所使用的操作系统和网络协议都依赖SHA-256。它是安全可靠的,得到了很好的支持。
SHA-3是美国国家标准技术研究所在2015年发布的一组散列函数家族。它是继SHA-1和SHA-2之后的最新一代散列函数标准。与SHA-1和SHA-2不同,SHA-3采用了全新的设计结构,称为基于海绵构造的Keccak算法。它提供了更高的安全性和更好的性能。SHA-3家族包括多个变体,如SHA-3-224、SHA-3-256、SHA-3-384、SHA-3-512等,分别生成不同长度的哈希值。SHA-3被广泛应用于密码学和安全领域,用于确保数据的完整性、验证数字签名、生成消息摘要等。相较于之前的散列函数,SHA-3具有更强的抗碰撞能力和抗预映像能力,提供了更高的安全性。尽管SHA-3已经发布并且被广泛研究和应用,目前仍然有许多系统和应用程序使用SHA-2或者较早的散列函数。SHA-3的采用还没有形成势头。
BLAKE2是一种现代的、快速且安全的散列函数,它可以生成不同长度的哈希值。注意标黑的快速,BLAKE2利用现在cpu架构以极快的速度进行散列。如果需要对大量数据进行散列,可以考虑BLAKE2。
0X02、数据完整性
1、什么是数据完整性?
数据完整性,字面意思理解就可以。同时它也是数据不会被意外修改的保证!那么,什么情况下会导致文件不完整捏?
感染病毒:比方说你的系统中了病毒,病毒感染了某个软件安装包或者某个可执行程序。那么该文件的完整性就被破坏了。
植入木马/后门:还有一种文件不完整的情况,是被别有用心的人植入木马或后门。比方说某些国内的软件下载站点,它们提供的 Windows 安装光盘镜像已经被安置了后门。
传输故障:这种情况主要发生在网络下载时。因为网络传输是有可能发生误码的(传输错误),另外还有可能下载到快结束的时候断线(没下载全)。这些情况都会导致你下载的文件不完整。
2、完整性校验
既然提到数据完整性,那就不得不讲讲完整性校验。
例如,很多知名的软件,除了在官网上提供下载,还会相应提供下载软件的散列值。当你下载好某个软件之后,先在自己电脑里计算一下散列值,然后跟官方网站提供的散列值对比一下。如果散列值一样,通常就说明没问题。
最主要的目的就是:查看数据有没有被篡改。
3、Yu9与黑客的小故事
Yu9的公司有一个文档管理系统,为了防止会黑客对其中文档的篡改,Yu9在系统中存入数据时,先使用散列函数计算出每份文件的散列值,定期把文档管理器中的文件散列值与存入时的散列值进行对比,判断文件内容有无被篡改或者损坏!
0X03、数据身份验证
继续回顾Yu9与黑客的小故事,假设黑客通过某种手段获取到了文件管理系统的访问和写入权限!他不仅可以更改文件,还可以更改文件的散列值。此时,Yu9就无法有效判断文件是否被篡改!
假设数据是test,生成的散列值是qwe。
判断数据有没有被篡改,把数据使用散列函数生成散列值,与qwe比较相同则说明数据完整未被篡改,不相同则说明数据被篡改。
黑客把数据改成test2,并生成散列值asd并替换掉qwe
此时存在系统中的数据是test2,散列值是asd。
Yu9判断数据有无被篡改就是通过把数据散列得到散列值与存入的散列值对比。
Yu9把test2散列后得到散列值asd,与此时的散列值对比一看一模一样。做出判断数据没被篡改。
但是此时数据已经被篡改。
此时,有人会疑惑,Yu9咋这么笨,散列值被篡改你都发现不了。或者说为啥不把散列值存到别的地方。嗯嗯嗯.....如果说系统中文件有一千个或者一万个,难道每一个都记得住吗?存到别的地方,又要如何做到一一对应呢?所以说这是没法改变的,必须存到一块!
聪明的Yu9要防御黑客,他有想到了另一个办法。在存入数据时,保证数据的完整性的同时又添加了一个功能,数据身份验证。通俗的说就是:数据的来源、谁创建了这个数据。
数据身份验证确保数据读取器可以验证数据写入者的身份!该功能的两个重要因素,秘钥、散列秘钥。下边给大家讲讲这两个概念!
1、秘钥
秘钥是什么?把它想象成钥匙,只有自己的钥匙才能打开自家的房门。那在计算机的世界中秘钥就是只有自己知道,很难被别人猜到的数字、字符串或者字符等等。
等等,到这就会有人到这就会说,那你说这不就是密码吗?简直一毛一样。
嗯嗯.....确实差不多,那就再补充几点,来区分密码和秘钥。
含义不同:密钥是一组用于加密和解密数据的参数,可以是数字、字符、符号或其他形式的数据;而密码通常指的是由字母、数字、符号组成的机密信息,用于身份验证或访问控制。
使用方式不同:密钥通常用于加密和解密数据或数字签名等加密操作;而密码则用于身份验证,例如登录电子邮件、社交网站或其他应用程序时需要输入的密码。
长度不同:密钥通常比密码更长,因为它需要足够强大以防止被破解。密码的长度通常在8-16个字符之间。
存储方式不同:密钥通常需要存储在安全的地方,例如硬件安全模块、密码保险箱或加密卡中,以保护其安全性;而密码通常存储在密码管理器、云存储服务或用户记忆中。
比较常见的秘钥:
随机数字
密码短语
2、秘钥散列
这个也好理解。还是继续回顾小故事!
Yu9为了保证文档管理系统中数据的安全,它添加了数据身份验证功能。具体怎么实现呢?
首先,他先生成一个秘钥:Yu9shidashuaigehahahaha
。然后再存入文件时,把文件+秘钥
通过散列函数生成一个散列值。把这个值和文件一块存入系统中。即使黑客把文件和散列值都改了。Yu9还是可以判断出数据有无被篡改。
说明:
假设数据是test,秘钥Yu9。test+Yu9生成的散列值qwe
黑客更改数据成test2, 生成的散列值asd并替换掉qwe。
此时Yu9使用,test2+Yu9生成的散列值与asd对比,发现不一样。判断数据被篡改。
3、HMAC函数
HMAC(Hash-based Message Authentication Code)是一种基于哈希函数的消息认证码算法,可以用于验证数据完整性和身份验证。它结合了加密哈希函数和密钥,以产生一个具有强韧性的消息验证代码。
具体来说,HMAC算法通过将密钥与消息组合,然后利用散列函数进行计算,生成一个消息认证码。这个消息认证码可以用于验证消息的完整性和身份验证。
HMAC算法的优点包括:
强韧性:HMAC算法具有强大的抗攻击性,能够防止大多数攻击,如生日攻击、碰撞攻击和长度扩展攻击等。
灵活性:HMAC算法可以使用多种哈希函数,例如MD5、SHA-1、SHA-256等,并且可以支持不同的密钥长度和消息长度。
安全性:由于HMAC算法使用了密钥,因此它可以提供更高的安全保障,防止数据被篡改和伪造。
总之,HMAC算法是一种基于哈希函数的消息认证码算法,具有强韧性、灵活性和安全性等优点,已经被广泛应用于网络安全、数据通信和数字签名等领域。
0X04、时序攻击
时序攻击是一种基于时间差异的侧信道攻击技术,是Yu9这样的安服仔接触不到的高度。
数据完整性和数据身份验证的验证都是通过比较散列值来完成。比较的过程就可能存在不安全的情况。
举例:
qwe
和qwa
是两个散列值,我们现在对它进行比较。为了节省时间,我们可以逐个字符进行比较,若第一个字符串都不相等,则他们就不相等,则可以结束比较。第一个相同之后,在进行比较下一个。依次类推....
假设比较一个字符串的时间是1s
qwe和asd比较,只要1s即可,第一个字符不行同,直接得出结果不相同
qwe和qsa比较,则需要2s,比较第一个相同花费1s,继续,比较第二个再花费1s,不同,总计2s得出结论。
qwe和qws,同理,需要3s
知道我要说什么了吗?
Yu9为了省事,整了一个定期验证数据的方法!现在系统中存入test,秘钥Yu9。test+Yu9的散列值为qwe。黑客可以拿到test数据,同时对数据进行散列可以知道散列值是3位,但是不知道秘钥。
黑客就不断调用验证数据的方法,传入构造的散列,比如:asd、qsd、qwd通过响应的时间的不同,来逐个字符破解。最终的破解出散列值。
0x05、 声明
遵纪守法
请严格遵守网络安全法相关条例!
此分享主要用于交流学习,请勿用于非法用途,一切后果自付。
一切未经授权的网络攻击均为违法行为,互联网非法外之地。
0X06、参考
https://www.cnblogs.com/goloving/p/15242372.html
https://www.liaoxuefeng.com/wiki/1252599548343744/1304227729113121
https://program-think.medium.com/扫盲文件完整性校验-关于散列值和数字签名-d9b3d4fd2e13
[美]丹尼斯·伯恩---python全栈安全