SHA-2算法

背景

前面介绍了SHA-1的详细内容。因为SHA-1已经被认为是不安全的,所以又开发了SHA-2。SHA-2可分为6种不同标准:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。其后数字表示摘要长度。

SHA-256和SHA-512是很新的散列函数,前者以定义一个word为32位,后者则定义一个word为64位。它们分别使用了不同的偏移量,或用不同的常量,然而,实际上二者结构是相同的,只在循环运行的次数上有所差异。SHA-224以及SHA-384则是前述二种散列函数的截短版,利用不同的初始值做计算。我们这里介绍SHA-512的内容,其余标准见标准文档

详细流程

SHA-512的最大数据长度为2^128 - 1。它的摘要长度为512位,分块长度为1024位。SHA-512是按照SHA-1的模型而来的,而SHA-1又是仿照MD5而来的,所以他们之间有很多相似之处,对于相似地方我们只简要说明一下

填充

填充为1024的倍数少128位,通用填充总是要进行的,即使已满足条件

添加长度

将原始信息长度写成128位形式填充到最后

分块

按1024一组进行分块

初始化链接变量

一共有8个初始化变量,实际上多少个初始化变量是由最后摘要长度决定的。如MD5为128位,就是4个,SHA-1位160位,就是5个。而SHA-512是512位,就是8个,但每个是64位:

A = 6a09e667f3bcc908
B = bb67ae8584caa73b
C = 3c6ef372fe94f82b
D = a54ff53a5f1d36f1
E = 510e527fade682d1
F = 9b05688c2b3e6c1f
G = 1f83d9abfb41bd6b
H = 5be0cd19137e2179

轮次操作

  1. 将初始化变量复制到abcdefgh中

  2. 将当前子块每64位一组,分16组

  3. 一共有80轮,每轮以当前块,abcdefgh和常量K[t],常量总共有80个,这些常数的取值是前80个质数的立方根的小数部分的前64位。每轮操作如下:

    temp1 = h + ch(e,f,g) + sum1(e)+wt+kt
    temp2 = sum0(a) + maj(a,b,c)
    a = temp1 + temp2
    b = a
    c = b
    d = c
    e = d + temp1
    f = e
    g = f
    h = g

    上面运算中t为轮次号,加法均是加完之后取2^64模,几个函数如下定义:

    ch(e,f,g) = (e and f) xor (not e and g)
    maj(a,b,c) = (a and b) xor (a and c) xor (b and c)
    sum1(e) = e>>14 xor e>>18 xor e>>41
    sum0(a) = a>>28 xor a>>34 xor a>>39

    对于每轮中的w,前16轮就是分好的16组子块,后面的w如下计算

    wt = a1(w(t-2)) + w(t-7) + a0(w(t-15)) + w(t-16)
    
    a1(x) = x>>1 xor x>>8 xor x>3
    a0(x) = x>>17 xor x>>19 xor x>10

    上面>>表示循环右移,>表示右移,空出的补零

  4. 80轮之后计算出的abcdefgh分别加上原来的ABCDEFGH作为处理下一个块的输入

和MD5与SHA-1一样,处理完所有块之后,最后的ABCDEFGH拼接到一起就是摘要信息。

题图来自unsplash:https://unsplash.com/photos/OIYrmG5FNFg