SHA-1算法

Olivia的小跟班 Lv4

题记

通常情况下我们需要对数据库中的用户密码加密,这是为了防止一旦数据库被攻击者获取,所有用户的密码都会被曝光,造成不可挽回的损失。而如果对密码进行加密,即使数据库被攻击者获取,也无法直接获得明文密码。本文主要介绍SHA-1、SHA-2这两种。

SHA-1

SHA-1(Secure Hash Algorithm 1)是一种密码学安全散列函数,它将任意长度的输入数据映射为160位的输出数据(也称为哈希值),并具有以下性质:

  1. 唯一性:对于不同的输入数据,SHA-1算法产生的哈希值是唯一的。
  2. 不可逆性:对于一个已知的SHA-1哈希值,无法通过逆向计算得到原始输入数据。
  3. 抗碰撞性:对于任意两个不同的输入数据,SHA-1算法产生的哈希值相同的概率极小,可以忽略不计。

SHA-1算法的具体实现过程如下:

  1. 数据填充:如果输入数据的长度不是512的整数倍,需要先进行填充。填充规则是在输入数据的末尾添加一个1和若干个0,直到数据长度达到512的整数倍。
  2. 分组处理:将填充后的数据按512位分组,每组称为一个消息块,共计N个消息块。
  3. 初始值设定:SHA-1算法需要使用一个160位的初始值,这个初始值是事先固定的,与输入数据无关。
  4. 消息扩展:对每个消息块进行消息扩展,通过一系列的变换将512位的消息块扩展为一个160位的哈希值。
  5. 压缩处理:将消息扩展的结果与初始值进行压缩,得到一个新的160位的哈希值。这个新的哈希值作为下一次压缩处理的输入,直到处理完所有的消息块。
  6. 输出:将最后得到的160位哈希值作为输出。

总的来说,SHA-1算法采用了一系列复杂的算法和数学运算,可以将任意长度的输入数据映射为一个唯一的、固定长度的哈希值,具有较高的安全性和抗碰撞性。

Go中的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
在这个函数中,我们首先创建一个 sha1.New() 对象,该对象表示 SHA-1 加密算法的实例。然后使用 o.Write([]byte(s)) 函数将要加密的字符串写入到 SHA-1 实例中。最后使用 hex.EncodeToString(o.Sum(nil)) 函数将 SHA-1 实例的哈希值转换为 16 进制字符串并返回。
*/

import (
"crypto/sha1"
"encoding/hex"
)

func SHA1(s string) string {
o := sha1.New()
o.Write([]byte(s))
return hex.EncodeToString(o.Sum(nil))
}

SHA-2

然而,SHA-1在现代密码学中已经被证明是不安全的。SHA-1算法存在一些漏洞,其中最严重的是碰撞攻击。碰撞攻击指的是找到两个不同的输入,使得它们经过SHA-1算法后得到相同的哈希值。这意味着攻击者可以伪造数字签名、篡改数据等,从而危及数据的安全性。由于SHA-1算法存在安全漏洞,建议不要使用它来加密数据库中用户的密码。

所以我们一般使用SHA-2,本文我们重点聊SHA-256。

SHA-256

SHA-256是SHA-2哈希算法族中的一员,它使用256位(32字节)哈希值,并采用更强的哈希函数来保证数据的安全性。SHA-256被广泛应用于各种安全领域,例如数字签名、密码哈希、SSL/TLS证书验证等。

在密码哈希方面,SHA-256可以用于将用户密码转换为一串随机的字符,而且同样的密码输入会得到同样的哈希值,但无法通过逆向运算得到原始密码。此外,可以使用盐值和迭代哈希等技术来增加破解密码的难度,从而提高密码存储的安全性。

需要注意的是,单独使用哈希函数来加密用户密码并不足以保障数据库的安全,还需要采取其他安全措施,例如使用SSL/TLS来加密传输、采用强密码策略、限制访问权限等。同时,为了防止被暴力破解,建议使用加盐、迭代哈希等技术,增加破解密码的难度。

SHA-256的具体流程如下:

  1. 数据填充:将消息填充为 512 位的块,使得填充后的长度等于 448 模 512,即长度为 448 或 960 或 1472 等。

  2. 添加长度:将消息填充后,再添加一个 64 位的数,表示填充前的消息长度。这个长度是以比特为单位的。

  3. 初始值设置:设置 8 个 32 位的常数作为初始值 H0-H7,这些常数是经过一定规则计算得到的。

  4. 块迭代计算:对填充后的消息进行分块处理,每个块的大小为 512 位。对每个块进行以下操作:

    a. 将块划分为 16 个 32 位的字,并将这些字存储在一个数组 W[0..15] 中。

    b. 将数组 W 扩展为 64 个字,这个扩展过程是通过迭代计算得到的。

    c. 初始化 8 个 32 位的变量 a, b, c, d, e, f, g, h,这些变量的初始值是 H0-H7。

    d. 进行 64 轮迭代,每轮迭代都会更新 a, b, c, d, e, f, g, h 的值,迭代的具体方式是通过一定的逻辑运算和位运算完成的。

    e. 在完成 64 轮迭代后,将 a, b, c, d, e, f, g, h 的值与 H0-H7 相加,得到新的 H0-H7 的值。

  5. 输出结果:对最后一块处理完成后,输出 H0-H7 的值作为哈希结果。

SHA-256的安全性基于其哈希函数的特性,包括强碰撞抗性、弱碰撞抗性、前缀抗性等。它是一种计算量较大的哈希函数,保证了消息的安全性和完整性。SHA-256已经被广泛应用于数字签名、SSL/TLS证书验证、密码哈希等领域。

Go中的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
)

func HashPassword(password string, salt string) string {
hasher := sha256.New()
hasher.Write([]byte(password + salt))
hash := hasher.Sum(nil)
return hex.EncodeToString(hash)
}

func GenerateSalt(length int) string {
salt := make([]byte, length)
_, err := rand.Read(salt)
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString(salt)
}
  • 标题: SHA-1算法
  • 作者: Olivia的小跟班
  • 创建于 : 2023-04-09 16:04:41
  • 更新于 : 2023-05-27 03:46:32
  • 链接: https://www.youandgentleness.cn/2023/04/09/SHA-1算法/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论