因为 password 与其hash之后的 password 是不可逆的。
graph LR
password-->hashed_password
Procedure
Without Hash
没有使用hash加密的web应用通常是这样的:
sequenceDiagram
User->>+Web: register with password
Web-->>-User: OK
Bad guy 1->>Web: get password from database or somewhere
Bad guy 1->>+Web: login
Web-->>-Bad guy 1: OK
Bad guy 2->>User: get password
Bad guy 2->>+Web: login with password
Web-->>-Bad guy 2: OK
盗用者可以通过Web系统的数据库或者在整个操作中的某一个漏洞中获取的密码,登录Web系统;盗用者当然也可以通过User那边获取密码,进行登录。
With hash
sequenceDiagram
User->>+Web: register with password
Web-->>-User: OK
Bad guy 1->>Web: get hashed password from database or somewhere
Bad guy 1->>+Web: login
Web-->>-Bad guy 1: failed
Bad guy 2->>User: get password
Bad guy 2->>+Web: login with password
Web-->>-Bad guy 2: OK
从上图,我们可以知道 hashed password 的主要功能的是预防 Server 方因为自身的过失导致密码泄露。另一点,就是确保 password 只存在 User 自己手上,其他人没有备份。
其他示例
容器中如何存储用户密码?
由于Docker容器会记录容器中的所有操作,所以如果我们:
1
$ echo "user1:user1password" | chpasswd
那么,盗用者查看容器的日志时,将会发现用户 user1
的密码是 user1password
。
sequenceDiagram
autonumber
Note right of User_1: without Hash
User_1->>+Container: set my password by [chpasswd]
User_2->>Container: find User_1 password
User_2->>+Container: login
Container-->- User_2: OK
为了解决该问题,可以使用 pre-hash password。
1
$ echo 'user1:$6$lAkdPbeeZR7YJiE3$ohWgU3LcSVit/hEZ2VOVKvxD.67.N9h5v4ML7.4X51ZK3kABbTPHkZUPzN9jxQQWXtkLctI0FJZR8CChIwz.S/' | chpasswd --encrypted
我们告诉了 chpasswd
使用是 hashed password,所以即便盗用者,那只能看到 hashed password。而当我们登录时,使用的是 password,而步是 hashed password。而盗用者知道的是 hashed password,即便反推出也无法得到真正 password。docker-sshd
sequenceDiagram
autonumber
Note right of User_1: with Hash
User_1->>User_1: hash password
User_1->>+Container: pass the hashed password to [chpasswd --encrypted]
User_2->>Container: find hashed password
User_2->>+Container: × fail to login