密码学学习笔记_02_散列与认证 密码学学习笔记_02_散列与认证 密码学学习笔记系列:密码学学习笔记_01_密码学综述密码学学习笔记_02_散列与认证 (本篇)密码学学习笔记_03_随机数与密钥派生密码学学习笔记_04_对称加密密码学学习笔记_05_公钥密码系统密码学学习笔记_06_数字证书与PKI密码学学习笔记_07_TLS通信协议 一、什么是Hash散列 散列函数(Hash function)又称散列算法、哈希函数,是一种从任意数据中创建相对较小的数字指纹的方法,目标数据长度不固定,转换后的数字指纹长度固定,转换过程不可逆。 散列并不是加密,加密是可逆的,而散列是不可逆的。 散列的目的是将消息或数据打乱、混合、压缩,使其数据量变小,并将数据的长度固定下来。 散列的结果叫做(hash values,hash codes,hash sums,或hashes),散列值可以是一个看起来很随机的数字,也可以是这个随机数字对应的字节数组或比特串,也可以是对这个字节数组进行编码之后的字符串。散列值有很多不同的称呼,例如、、、、、等等。 1.1 散列算法的特征 散列算法具有以下特征:散列算法具有不可逆性,即,无法有效地通过散列值逆推明文。散列算法的明文通常可以很长,而散列值则固定长度。相同的明文产生相同的散列值,如果两个明文的散列值不同,那么这两个明文一定不同。不同的明文大概率产生不同的散列值,但依然有较小的概率产生相同的散列值。这叫。一个明文少许改变部分输入,那么会产生一个完全不同的散列值。这叫雪崩效应,是密码学中混淆与扩散原则的体现。 1.2 散列算法的用途 由于散列算法所具备的特征,它常常被用于以下场景:网络传输的校验和: 在网络传输(比如从网站下载资源)过程中,为了避免传输过程中发生数据丢包等问题,网站往往会提供一个对应下载文件的校验和文件,这个校验和文件就是目标文件的散列值,于是在客户端下载完目标文件后,只要用相同算法对下载到本地的文件做一次散列计算,然后与网站提供的校验和文件进行对比,就能确定下载好的文件是否与网站上的文件一致。确保传递消息的真实性与完整性: 类似校验和,发送消息的一方将原消息与其散列值一起发送,接收方通过验证原消息的散列值与接收到的散列值是否一致来确保消息的真实性与完整性。实际的安全网络传输中当然不会如此原始简单,比如tls通信中,在握手完成后的通信中就用到了散列函数来验证消息,但并不是简单的直接使用散列,而是结合握手时协商好的相关密钥对消息做认证码(MAC)验证。电子签名:电子签名一般用于网络中的身份验证,由数字签名算法实现。而数字签名算法中往往需要一个散列函数对签名主体先做一次摘要计算,在提高安全性的同时,也确保了签名内容不会过长。(数字签名的一个特点是签名内容越长,签名就越长。)保存敏感资料如密码: 在服务端保存用户密码等敏感资料时,可以利用散列的特性进行保存,在无法逆推明文的基础上,可以通过散列计算验证密码是否正确。散列表实现快速查找: 即HashTable,利用key的散列值映射到内存地址从而快速读写value。HashTable的场景,对散列计算速度要求较高,而对散列碰撞的要求相对较低,因此两个不同key计算到同一个内存地址上的概率相对较大。因此HashTable的实现,比如Java的HashMap,对哈希冲突的场景都做了特殊处理(同一地址上用链表或红黑树结构存储)。还有一些其他用途,不再一一列举。注意,散列值在不同的使用场景下往往使用不同的称呼:用来校验文件时,往往称之为,英文是;用来确保消息真实性和完整性时,往往称之为(Digest)或(Finger Print);更多时候则可能直接称之为或(Hash Value)。称呼往往体现出其使用目的。 1.3 散列算法的分类 散列算法一般可以被分为算法和算法;算法中又可以分为安全的算法和不安全的算法;另外还有一种特殊用途的抗ASIC哈希算法。 1.3.1 密码学哈希和非密码学哈希 散列算法一般被分为和。 所谓,英文是,指的是用于保证密码学安全性的散列算法。所谓保证密码学安全性,是指很难发生哈希碰撞,或者很难被找出散列前的明文,并且散列值表现出随机性。的关键指标是抗碰撞性,也就是发生哈希碰撞的可能性。抗碰撞性越好,发生碰撞的可能性就越低,也就越安全。在使用时,一般都会将不会发生碰撞作为设计前提。很多资料直接将翻译为,被翻译为。。。这种偷懒的翻译不是很好,因为的意思是指满足密码学安全性要求的哈希函数,直接翻译为容易让人误解这种哈希是不是跟加密(encrypt)有关,其实跟加密(encrypt)是没有关系的。因此这里采用的翻译。 而,只是尽量避免非恶意输入带来的哈希碰撞,对抗碰撞性的要求并不高。比如检测数据中的意外变化(CRCs, 循环冗余校验),或者HashTable中将不同的对象快速分配到不同的地址空间,这些场景并不要求不能发生碰撞,只要尽量较少碰撞就可以了。 判断一个哈希算法是不是的原则是,看它设计出来的目的是什么,是否是要确保密码学安全性,即拥有足够高的抗碰撞性。 以HashTable为例,它对散列计算的速度要求远大于抗碰撞性要求,所以采用的就是某个很简单的算法。比如java的HashMap所采用的散列算法,就是遍历对象的每个字节不断乘以一个质数(31)再叠加。由于这种哈希算法有较高的可能发生哈希碰撞,再考虑到根据哈希值计算的地址发生冲突的可能性,所以java的HashMap专门设计了发生碰撞后的处理逻辑,在相同地址上使用链表或红黑树存储发生碰撞的多个对象。 只能用在数据校验、HashTable等对抗碰撞性要求低的场景,而的应用场景不但有数据校验,还有电子签名、密码保存、数据指纹、伪随机数生成等场景。数据指纹的一个典型例子,就是git等文档管理系统中的文档ID或版本ID,这类系统假设散列值不会发生碰撞,才能保证ID的唯一性,因此对抗碰撞性要求很高。伪随机数也是的一个应用场景,它在最初的随机数种子(seed)的基础上,做一次哈希计算就得到一个随机数,为了保证随机数不重复,它对抗碰撞性的要求也很高。 1.3.2 不安全的算法 对于,使用时是假设它不会发生碰撞的。但如果一个密码学哈希算法被证明在当下计算机的计算能力内出现碰撞的可能性较高,或出现过碰撞,就会被标记为了,将不再被推荐作为密码学哈希算法使用。比如MD5算法,它最开始是作为被设计出来的,但随着计算机能力的发展,MD5被证明实际出现碰撞的可能性较大,于是MD5就被标记为算法,实际上只能在很有限的一些场景里作为来使用。关于密码学哈希算法是否安全的判断标准的简单说明: 如果理论上证实可以用比暴力穷举更快的速度激活成功教程一个算法,那么它就是被攻破的;如果能在一个合理时间内完成激活成功教程,则认为这个密码学哈希算法是不安全的。目前被证明不安全或安全性有争议的密码学哈希算法: 、系列、系列等等。目前认为安全的密码学哈希算法: 系列(包括、、等)、SHA-3系列(包括、、、等)、等等 1.3.3 主流的算法 目前国际上主流的算法是与,国内主推的则是国密标准的。以为例,256代表其散列值的长度是256位,即32个字节。一般来说,散列值长度越长,抗碰撞性就越好,所以拥有比更好的抗碰撞性。而在散列值长度相同时,系列算法被认为比系列拥有更高的安全强度,其碰撞概率更低。的散列值长度固定为256位,在安全强度上与相当。 1.3.4 抗ASIC哈希算法 除了与,还有一类用途特殊的散列函数:某些区块链中的共识算法中会使用一种计算密集和内存密集的哈希函数用于PoW工作量证明。这些哈希函数在设计上就需要消耗大量计算资源(CPU与内存)和时间,并且难以通过硬件来实现计算加速。这种哈希函数被称为(Application Specific Integrated Circuit, 专用集成电路)的哈希函数。大部分工作量证明(Proof-of-Work)算法,都是要求计算出一个满足特定条件(称为挖掘难度)的哈希值。因为哈希值是不可预测的,为了找出符合条件的哈希值,矿机往往需要计算数十亿个不同的哈希值,才能从中找出一个符合条件的哈希值。比如,一个工作量证明问题可能会被定义成这样:已有常数,要求找到一个数,使的前十个比特位都为。 常见的PoW工作量证明哈希函数如以太坊的、以及Zcash、Bitcoin Gold和其他一些区块链中使用的 ,它们的计算速度很慢,通常要使用大显存的GPU,或强大的CPU配合大量高速内存(DDR4以上)来执行这类算法。 二、SHA256散列算法 算法是系列算法中应用最广泛的一个算法。 是(安全散列算法2)的缩写,它是一个算法集合,由美国国家安全局研发,由美国国家标准与技术研究院(NIST)在2001年发布,属于SHA算法之一,是的后继者。包含了6个具体的算法:SHA-224SHA-256SHA-384SHA-512SHA-512/224SHA-512/256 这些具体算法之间的区别主要是散列值的长度,迭代计算的次数不尽相同。它们的基本算法过程是一致的,这里以最常用的算法为例进行说明。 2.1 SHA256算法过程 SHA256的整体算法过程如下图所示:
该过程说明如下:对明文进行补位处理,使明文长度为512的整数倍。具体补位处理见后续章节。将补位后的明文拆分为n个512位的块。对n个块进行迭代,依次对每个块做SHA256压缩运算,最终得到8个散列字(一个字4个字节)。将最终的8个散列字拼接起来,得到最终的散列值,共32个字节,256位。SHA256算法中,为了计算出最后的固定长度为256位的散列值,将256位拆分为8个(word),一个的长度为4个字节。这里我们称之为8个散列字。 下面对上述过程中的具体步骤进行详细说明。 2.2 补位处理 SHA256的补位目的是确保明文可以被拆分为512位的块,因此补位后明文的比特位长度是512的整数倍。 补位的结构如下:首位: 补位的首位固定为。中间位: 中间位是N个。N满足条件:。末尾位: 补位的最后固定为64位,具体的值是原始明文长度的二进制数值。因此SHA256的明文长度不能超过。注意,即使原始明文位数正好是512整数倍,也依然要做补位处理。 2.3 SHA256的压缩函数 SHA256的核心是对每个块做的压缩函数计算。该函数是使用每个明文块的数据对8个散列字进行一系列的位运算得到新的8个散列字。其基本运算过程是:对当前明文块做消息扩展运算得到一组64个字。参考。对上一轮明文块压缩计算后得到的8个散列字做散列字压缩运算,得到本轮的8个散列字。参考。如果当前块是第一个块,则使用8个初期散列字(参考)作为上一轮明文块压缩计算后得到的8个散列字。 2.3.1 SHA256压缩函数中涉及到的运算 SHA256压缩函数中涉及到的相关运算包括::32比特异或运算:32比特与运算:32比特非运算:32比特右移n位:32比特循环右移n位:左向赋值运算 2.3.2 SHA256明文块消息扩展 对每个明文块做消息扩展运算,得到一组64个字:先将明文块拆分为16个字(每个字4字节32位),作为前16个字: ;基于前16个字,按照下面的迭代公式进行迭代计算,得到后48个字: 迭代公式: 2.3.3 SHA256散列字压缩运算 对上一轮明文块压缩计算后得到的8个散列字做散列字压缩运算: 是上一轮压缩计算后得到的8个散列字(即),是本轮压缩计算后得到的8个散列字(即);是一个数组,包含64个事先定义好的常量,参考。是8个临时变量,表示8个临时变量分别与上一轮压缩计算后得到的8个散列字一一对应相加。、、、、、是64次迭代计算中的临时变量。 2.3.4 SHA256初期散列字 8个初期的散列字在SHA256中是写死的8个常量: 这8个初期散列字是对自然数中前8个质数(2,3,5,7,11,13,17,19)的平方根的小数部分取前32bit而来。 2.3.5 64个事先定义好的常量 64个字的遍历内部使用的64个事先定义好的常量,与8个初期散列字类似,取自自然数中前面64个素数的立方根的小数部分的前32位, 如果用16进制表示, 则相应的常数序列如下: 2.4 SHA256伪代码 SHA256完整过程的伪代码如下: 三、SM3散列算法 SM3是我国国家标准的商用密码体系中提供的一种密码学哈希算法,首版由国家密码管理局于2010年12月17日发布。目前最新版本为2016年发布的。在线文档: http://c.gb688.cn/bzgk/gb/showGb?type=online&hcno=45B1A67F20F3BFC391E9278F5E 在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,算法公开,安全性及效率与相当。 3.1 SM3算法过程 SM3算法过程与SHA256基本相同,只是核心的压缩函数的具体实现逻辑不同。SM3的整体算法过程如下图所示:
该过程说明如下:对明文进行补位处理,使明文长度为512的整数倍。具体补位处理见后续章节。将补位后的明文拆分为n个512位的块。对n个块进行迭代,依次对每个块做SM3压缩运算,最终得到8个散列字(一个字4个字节)。将最终的8个散列字拼接起来,得到最终的散列值,共32个字节,256位。和SHA256一样,SM3里同样为了计算出最后的固定长度为256位的散列值,将256位拆分为8个字(word),一个字的长度为4个字节。这里我们称之为8个散列字。 下面对上述过程中的具体步骤进行详细说明。 3.2 补位处理 SM3的补位处理与SHA256一样,这里不再赘述,可直接参考章节。 3.3 SM3压缩函数 SM3与SHA256的区别就是压缩函数的具体逻辑不同,但该函数的对外接口是一致的,都是使用每个明文块的数据对8个散列字进行一系列的位运算得到新的8个散列字。二者的区别主要有:SM3将每个明文块扩展为132个字,分为两组,第一组68个字,第二组64个字;而SHA256只扩展为一组64个字。SM3的8个初期散列字与SHA256的不同,SHA256是对自然数中前8个质数(2,3,5,7,11,13,17,19)的平方根的小数部分取前32bit而来,SM3的初期散列字并未说明其来源。SM3的压缩函数中的一系列位运算逻辑与SHA256不同,其中值得注意的是,SHA256在压缩函数的迭代运算中需要64个事先定义好的常量,而SM3则不需要,因为SM3对明文块扩展了两组字,其中一组可以用来替代那64个常量。 SM3的压缩函数的过程:对当前明文块做消息扩展运算得到两组字,第一组68个字,第二组64个字。参考。对上一轮明文块压缩计算后得到的8个散列字做散列字压缩运算,得到本轮的8个散列字。参考。如果当前明文块是第一个块,则使用8个初期散列字(参考)作为上一轮明文块压缩计算后得到的8个散列字。 3.3.1 SM3压缩函数中涉及到的运算与公式 SM3压缩函数中涉及到的运算与公式包括::32比特与运算:32比特或运算:32比特异或运算:32比特非运算:32比特循环左移n位:左向赋值运算:模运算,即取余:置换函数,具体逻辑为:置换函数,具体逻辑为:布尔函数,具体逻辑为: 在区间时:; 在区间时::布尔函数,具体逻辑为: 在区间时:; 在区间时: 3.3.2 SM3明文块消息扩展 对每个明文块做消息扩展运算,得到两组字,第一组68个字,第二组64个字:先将明文块拆分为16个字(每个字4字节32位),作为前16个字: ;使用迭代公式1,以及前16个字,迭代计算第17到68个字,得到第一组68个字。使用迭代公式2,以及第一组68个字,迭代计算第二组64个字。 迭代公式1伪代码: 迭代公式2伪代码: 3.3.3 SM3散列字压缩运算 对上一轮明文块压缩计算后得到的8个散列字做散列字压缩运算: 是上一轮压缩计算后得到的8个散列字(即),是本轮压缩计算后得到的8个散列字(即)。是一个常量的函数: j在区间时,返回常量; j在区间时,返回常量。是本轮压缩计算的8个临时变量,表示8个临时变量分别与上一轮压缩计算后得到的8个散列字一一对应做异或运算。、、、是64次迭代计算中的临时变量。 3.3.4 SM3初期散列字 8个初期的散列字在SM3中是固定的8个常量: 四、MAC与HMAC 散列可以用于消息认证,但还不足够安全,如果攻击者能够获知散列算法,那么就可以在通信中间拦截到消息以后,篡改明文并重新生成摘要,此时消息接收方无法检查出明文消息是否已经被篡改。因此MAC(消息认证码)与HMAC(基于哈希的消息认证码)出现了。 4.1 什么是MAC 消息认证码是,缩写为,它是这样一种技术: 消息认证码是对消息进行认证并确认其完整性的技术。通过使用发送者和接收者之间共享的密钥,就可以识别出是否存在伪装和篡改行为。 MAC就是通过一起计算得出的一个类似散列摘要的值。但不同的是,散列摘要只能保证消息的完整性,即生成该摘要B的明文A是完整无误的。而MAC算法能够在保证消息完整性的基础上,进一步保证消息未被篡改,即判断确实发出的是明文A而不是明文C。 MAC的关键在于通信双方需要事先约定一个共同的密钥,这样即使攻击者获知的具体的算法,因为不知道密钥,也无法在篡改明文后计算出正确的MAC。当然,通信双方如何安全地协商出密钥就是另一个非常重要的问题了,这个问题在以后的密钥交换算法相关章节中学习。 MAC是一种约定,接口,它可以有不同的实现,比较常用的是HMAC(基于哈希的消息认证码)。MAC也有其他的实现方式,比如基于分组加密的实现,用的很少,这里就不了。 4.2 HMAC算法 HMAC是的缩写,就是基于哈希的消息认证码,可以组合各种散列算法来实现。比如使用了这个密码学散列算法的就是,使用了的就是。 那么,HMAC是如何使用散列算法来实现MAC的呢?可以用下面这个公式来表述: 表示密钥,是明文,是该HMAC组合的散列函数,比如。是补位或散列之后的密钥:检查的长度,如果小于散列函数的blocksize(记为B),则向右填充; 如果大于B,则使用散列函数对进行散列; 长度相同则沿用。是外部填充内容,重复B次的字节数组。是内部填充内容,重复B次的字节数组。是异或运算,是拼接处理。 上述公式的伪代码如下所示: 4.3 利用HMAC实现安全的用户登陆认证 在不安全的网络环境中实现用户登陆认证时,应该要避免直接将用户登陆时输入的密码明文传输到后台。如果不使用https的话,可以考虑利用HMAC算法来实现一个相对安全的用户登陆认证。客户端发出一个登陆请求,此时只发送了登陆账户名,并没有发送用户密码。服务端受到该登陆请求后,检查账户是否存在,存在则生成一个随机数,保存到该用户的会话session中,并返回该随机数给客户端。客户端收到请求响应,拿到随机数,作为密钥,与密码明文一起做HMAC运算得到MAC值,然后第二次向服务端发出携带了密码MAC的登陆请求。服务端接收到这个携带了密码MAC的登陆请求后,从数据库取出用户密码,将会话session中的随机数作为密钥,使用与客户端相同的HMAC算法计算MAC,如果与客户端发来的MAC相同,则用户登陆认证通过。数据库中是否存储密码明文是另一个安全问题,这里讨论的是如何避免明文传输密码。 在这个登陆认证过程中,攻击者中间拦截只能看到账户名,随机数与MAC,无法逆推得到密码明文。只要每次登陆生成不一样的随机数,那么每次的MAC也不一样,攻击者就难以通过统计一段时间的登陆数据来尝试激活成功教程密码。 五、小结 密码学提供了很多密码学哈希算法,比如、,可以用于数字签名、MAC认证、随机数发生器等其他密码学算法。而HMAC就是利用密码学哈希算法实现的用于消息认证的算法。HMAC相比单独的散列算法,能够防止消息伪造或篡改,更加适用于不安全的网络环境。 接下来要学习的是随机数与密钥派生,它们经常使用散列或HMAC算法:密码学学习笔记_03_随机数与密钥派生
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/26543.html