简介
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(DSS,Digital Signature Standard)里面定义的数字签名算法(DSA,Digital Signature Algorithm)
对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要
SHA1有如下特性:
- 不可以从消息摘要中复原信息
- 两个不同的消息不会产生同样的消息摘要
发展历史
SHA-1算法的原理基于MD4和MD5消息摘要算法的设计原理,但是具有更保守的设计。
SHA-1是美国政府Capstone项目的一部分。该算法的原始规范于1993年以美国政府标准机构NIST(国家标准与技术研究所)的标题《Secure Hash Standard》出版。这个版本通常称为SHA-0。它在出版后不久被国家安全局撤回,并在1995年由SHA-1取代。
SHA-1与SHA-0的不同之处仅在于,其压缩功能的消息调度中单个按位旋转。根据国家安全局的说法,这是为了纠正原始算法中的缺陷,增强了其加密安全性,但没有提供任何进一步的解释。不过确实有公开技术能攻击SHA-0。
应用
密码体系
SHA-1构成了许多广泛使用的安全应用和协议的一部分,包括TLS和SSL,PGP,SSH,S / MIME和IPsec。这些应用程序也可以使用MD5(MD5和SHA-1均来自MD4)。
分布式版本控制系统(如Git,Mercurial和Monotone)也使用SHA-1散列来识别修订,并检测数据损坏或篡改。该算法也被用于任天堂的Wii游戏控制台,以便在引导时进行签名验证,但在固件的第一次实验中,存在允许攻击者绕过系统的安全性方案的一个重要缺陷。
SHA-1和SHA-2是法律要求在某些美国政府应用中使用的哈希算法,包括在其他加密算法和协议中使用,用于保护敏感的未分类信息。 FIPS PUB 180-1还鼓励私营和商业组织采用和使用SHA-1。SHA-1正在从大多数政府用途中退休,美国国家标准技术研究所表示:“联邦机构应尽快停止使用SHA-1应用程序,这些应用程序需要抗冲突,并且必须在2010年之后使用SHA-2系列的哈希功能进行这些应用。”,虽然后来放松了。
首先推动安全散列算法出版的是已合并的数位签名标准。
SHA 散列函数已被做为 SHACAL 分组密码算法的基础。
数据完整
Git和Mercurial等版本控制系统使用SHA-1不是为了安全,而是确保数据没有因意外的损坏而改变。 Linus Torvald说,关于Git:
如果您有磁盘损坏,如果您有DRAM损坏,如果您有任何问题,Git会注意到它们。这不是一个问题,是否是一个保证。你可以让人恶意破坏,但他们不会成功。没有人能够破解SHA-1,但关键是SHA-1,就Git来说,甚至不是一个安全功能。它纯粹是一致性检查。安全部件在别的地方,所以很多人都认为,由于Git使用SHA-1,SHA-1用于加密安全的东西,他们认为,这是一个巨大的安全功能。它与安全无关,只是你可以得到的最好的哈希。
我保证,如果您将数据放在Git中,您可以信任五年后,从硬盘转换为DVD到任何新技术,并将其复制的五年之后,您可以验证你收到的数据是你输入的完全相同的数据。
我关心的一个原因是内核,我们在BitKeeper的一个网站上有一个突破,人们试图破坏内核源代码存储库。然而,Git不需要SHA-1的第二个preimage抵抗作为一个安全功能,因为它总是喜欢保持对象的最早版本的情况下发生冲突,防止攻击者偷偷覆盖文件。
SHA加密原理
位串和整数的定义
下面有关位串和整数的术语将被使用:
一个十六进制数是集合{0, 1, … , 9, A, … , F}中的元素,表示4-bit二进制串。例如:7 = 0111, A = 1010。
一个字表示32-bit二进制串,或者是8个十六进制数。把一个字转换成二进制串,等价于把每一个十六进制数转换成4-bit二进制串。
0和2 ^ 32 - 1之间的整数可以表示为一个字。整数的最低有效四位是由最右边的十六进制数字表示。示例:整数291 = 2^8 + 2^5 + 2^1 + 2^0 = 256 + 32 + 2 + 1由十六进制字00000123表示。如果z是整数,0 <= z < 2^64,则z =(2^32)x + y其中0 <= x < 2^32和0 <= y < 2^32。 由于x和y可以表示为字X和Y,z可以表示为一对单词(X,Y)。
block=512-bit二进制串。一个block可以表示成16个字。
对字的操作
下面的逻辑运算符将被用于字操作:
按位逻辑运算:
X AND Y = X和Y的逻辑“和”
X OR Y = X和Y的逻辑“或”
X XOR Y = X和Y的逻辑“异或”
NOT X = X的逻辑“补”Example: 01101100101110011101001001111011 XOR 01100101110000010110100110110111 -------------------------------- = 00001001011110001011101111001100
操作X + Y定义如下:字X和Y表示整数x和y,其中0 <= x < 2^32和0 <= y < 2^32。对于正整数n和m,令n mod m是将n除以m的余数。计算z =(x + y)mod 2^32。 那么0 <= z < 2^32。将z转换为字Z,并定义Z = X + Y.
循环左移运算S ^ n(X),其中X是一个字,n是0 <= n <32的整数,由如下定义:S^n(X)=(X << n)OR(X >> 32-n)。其中X << n:舍弃X的最左n位,然后将结果填充到右边的n个零(结果仍然是32位)。X >> n是丢弃X的最右n位,然后在左边填充n个零。因此,S^n(X)等价于X向左移动n个位置的循环移位。
消息填充
SHA-1用于计算作为输入的消息或数据文件的消息摘要。消息或数据文件应该被认为是一个位字符串。消息的长度是消息中的位数(空消息的长度为0)。如果消息中的位数是8的倍数,为了紧凑,可以以十六进制表示消息。
消息填充的目的是使填充消息的总长度为512的倍数。当计算消息摘要时,SHA-1顺序处理512位的块。作为总结,随后是“1”后面跟着填充的“0”,64位的消息长度附加到消息的末尾以产生长度为512 * n的填充消息。 然后填充的消息由SHA-1处理为n个512位块。
要求输入到SHA-1的消息长度为L < 2^64,消息填充步骤如下:
先填充一个“1”。
Example: 原始消息为: 01010000 填充过后为: 010100001
再填充“0”。“0”的个数由原始消息长度决定。最后64-bit用原始消息的长度填充。
Example: 原始字符串用二进制表示为: 01100001 01100010 01100011 01100100 01100101. 经过第一步后: 01100001 01100010 01100011 01100100 01100101 1. 如果 L = 40, 现在填充的位有41个并且还有407个"0"被填充,使得总共填充448位。现在填充后的结果用十六进制表示为: 61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
获取原始消息长度L的二进制表示。如果L < 2^32,那么第一个字都是零。然后将这两个字追加到填充的消息中。