哈希函数SHA-1(Secure Hash Algorithm 1)由美国国家安全局于1995年首次发布,对输入消息生成160位的消息摘要,广泛应用于数字签名等诸多领域。后来随着密码分析人员的研究,发现其存在缺陷并可被实施攻击,逐渐被更安全的SHA-2或SHA-3代替。
尽管被抛弃,但是由于其曾经广泛的使用,存留的很多软件系统无法短期内完全升级,所以未来很长一段时间,仍然会看到SHA-1的身影,例如开发人员经常使用的版本管理软件Git,每次提交代码的commit ID 就是使用SHA-1来计算的。
哈希函数的算法实现,高级编程语言通常都会封装,供开发人员直接调用,一般无需了解其详细计算过程,其运算逻辑和程序编码并不难实现,难点在于理解算法的设计思想,需要具备深厚的数学、密码学背景才可能理解。
下面以消息 abc 为例,逐步解说其计算过程。
本文使用的位运算符号说明:
取反
按位与
按位或
异或
左移
循环左移
循环右移
相加模
原始消息转为二进制
a 二进制 01100001
b 二进制 01100010
c 二进制 01100011
对消息分组,每组512位长度
abc 的二进制总长度24位,不够512位,需要补位
补位步骤:
1. 先在abc后面补1
2. 规定末尾64位表示原始消息的长度
abc的二进制长度为24,24的二进制为11000,
末尾就是
3. 中间剩下423个空位全部补0
( 3x8 ) + 1 + 423 + 64 = 512
这样补位后总长度为512位,刚好凑足1组。
补位完毕,此时消息为:
补位规则:
补位后的长度为512的整数倍。
如果消息长度为447,补1后,刚好448,此时不需要补0,直接补末尾64位即可,消息被分为1组。
如果消息长度为448,补1后,达到449位,这个时候第1组剩下63位,不够64位,就需要补63位0,再继续补448个0,最后补64位消息长度,消息被分为2组。
本例只分了一组,如果消息被分为多组,记为
将按32位切割为16组,标记为
......
现在已经有到
还需要生成到
生成函数:(向左滑动查看全部公式)
函数的定义:
按照上面的函数最终生成块到共组
设定初始哈希值
这5个初始哈希值是算法设定不变的,
仅用于第一组消息的处理,
处理后续分组的时候使用前一组计算的结果;
定义5个临时变量并赋值
然后开始80轮的循环计算(轮次用t表示)
算法逻辑图
常数定义
函数定义
以第一轮计算举例(T为临时变量):
可以看到,主要的变化是对下一轮A的计算,
其他几个变量都是上一轮变量的重新赋值,
以上步骤循环计算80轮,最后把的结果和其初始值执行+运算
依次顺序拼接就是的哈希值;
如果有分组将的结果作为的初始哈希值继续计算。
哈希函数的种类很多,但同类型的函数计算过程都有相似的步骤,熟悉其中一种,有助于理解其他函数的计算过程,同时对于从事信息安全的人员来说,有助于理解相关攻击方法的原理,比如长度扩展攻击等。
参考文献
[1] https://tools.ietf.org/html/rfc3174
[2] https://en.wikipedia.org/wiki/SHA-1
[3] https://csrc.nist.gov/csrc/media/publications/fips/180/2/archive/2002-08-01/documents/fips180-2.pdf