为了保护用户密码,我知道服务器存储用户密码的方式是加盐后再哈希。 但是问题是服务器是需要获取用户明文密码后再进行处理的,如果服务器被黑客控制(不管通过什么方式),修改了代码,将用户登录后的明文密码窃取了下来,那么用户的密码就不安全了。(不讨论如何加强服务器的安全措施)。 可不可以在浏览器端就对用户的密码进行哈希加密?服务器只对这个哈希密码进行再加盐哈希存储。 这里又有个问题,就是用户输入密码后,生成的哈希值必须相同,否则服务器就无法验证了(或者有没有一种密码哈希算法支持这种不同密码的验证?),但这就给彩虹表攻击提供了机会,当然用户的密码也可以先加盐再哈希,但如果黑客连这个盐值也获取了,重新制作彩虹表也是可以的。 我想问下有没有更好的方案防止用户密码泄露?
1
xuanbg 2023-08-28 07:45:49 +08:00
想不通为什么“需要获取用户明文密码后再进行处理”。不是客户端加盐哈希给你,你只管存就行了吗?验证密码也是一样,你只管比对和你存数据库的那个字符串是否一致就行,你管他明文是什么。
|
2
xuanbg 2023-08-28 07:51:13 +08:00
当然,要更安全一点的话,就是客户端给你密码的哈希值,然后你收到后再加盐哈希一次存起来。验证的时候也是客户端给你传密码的哈希值,你加盐哈希后再和数据库存的值进行比对。至于彩虹表,你想多了,只对弱密码有效。加盐就是为了保护弱密码的,如果你的盐泄露了,那这弱密码就失去了防护。那怎么办呢?简单得很,改成强密码呀。如果用户不想保护自己的账号,你也没必要替他操这个心。
|
3
MrSheng 2023-08-28 09:27:12 +08:00
1 、当选定一种哈希算法,比如 md5 后,任何语言的各种库实现都会对相同对象输出相同值,不存在所谓的用户输入密码后输入哈希值不同的问题。
2 、诚如 #2 所说,加盐是为了保护弱密码的,如果盐值泄漏但是加盐算法不泄漏的话,一样没招(加盐并不是简单的把盐值直接拼在用户密码的哈希值之后) 3 、对于彩虹表来攻击,有没有盐值无所谓,就是要量大 4 、正确的做法就是前端计算用户的哈希值(不仅仅只针对密码字段)传给后端,后端加盐存储。 |
4
nulIptr 2023-08-28 09:27:15 +08:00 via iPhone
除了楼上说的,还有一点是数据库加盐是防拖库。
你说的传输过程加盐是防中间人。 安全这个事情是全链路配合,比如说你用 vault 或者是 k8s 里的 secret 存数据库连接字符串,但是某个开发为了方便,直接在 log 里面打印出来这个连接串,这时候你的 vault 安全性就是个笑话 |
5
rocksolid 2023-08-28 09:30:42 +08:00
服务器被黑客控制,还要用户密码干嘛,我都控制门禁了还要把算盘打到几张门卡上面。。。
|
6
yinmin 2023-08-28 11:45:43 +08:00
前端不加盐做哈希,是毫无意义的,因为对于黑客而言,密码哈希值就是一个用于前后台交互的明文密码。前端加盐做哈希,就需要服务器保存密码原文,即使密码加密保存,也更容易拖库后被解密。
|
7
yinmin 2023-08-28 11:52:21 +08:00
金融行业是使用密码机的硬件设备的。前端加密,服务器验证是送到密码机去校验的,密码机有国家证书的,可以被认为是安全的,被拖库的责任也由密码机背锅,板子打不到开发运维头上。
|
8
yinmin 2023-08-28 11:56:39 +08:00
商业软件的做法就是: https 加密传输密码明文,服务器加盐哈希保存,每个用户有一个随机产生的独立盐。金融行业软件的做法就是:买 1 个加密机硬件,根据说明书写。
|
9
liuidetmks 2023-08-28 12:05:14 +08:00
别用 md5 了,早就不行了。
推荐使用 blake ,最快,安全性不弱于 sha3 , 自带盐功能(当然也可以不设置 |
11
iX8NEGGn 2023-08-28 17:00:19 +08:00 via iPhone
“但如果黑客连这个盐值也获取了,重新制作彩虹表也是可以的”,一个密码一个随机盐,然后将盐和哈希一起发送到后台,黑客能获取到盐那必然能获取到哈希甚至原密码,还考虑什么彩虹表。还是你以为前端直接写死一个固定的盐,然后被黑客查看代码获取?盐要在内存中随机生成,一个密码生成一个盐,不要固定用一个值。
|
12
iX8NEGGn 2023-08-28 17:43:48 +08:00 via iPhone
貌似我理解错了,你是假设服务器被入侵,用户传原密码到服务器验证时原密码泄漏,那前端的盐确实只能用固定值了,否则无法验证。
你可以去看看 Bitwarden 的安全架构,或许有帮助,好像它的登录原密码貌似也不传到后端。 |
13
XiiLii OP @iX8NEGGn 是的,用户密码只有用户自己知道,在离开客户端前密码就已经被哈希处理,Bitwarden 应该就是做这种哈希处理的。但是对于用户来说,他基本不想使用任何的额外软件来管理自己的密码,如果可以,客户端就应该帮用户进行哈希,如果只是简单的哈希,会被彩虹表攻击,加盐的盐值泄露也不行。
|
15
iX8NEGGn 2023-08-28 18:40:49 +08:00
你直接参考 Bitwarden 实现吧,和你的需求符合,它把用户名邮箱作为盐,然后经过多次 PBKDF2 处理。地址: https://bitwarden.com/help/bitwarden-security-white-paper/
|
16
yinmin 2023-08-28 20:45:55 +08:00
也许 2 次加盐哈希是更安全的方式。有 3 个盐,全局盐 Salt 写死在程序里,每个用户随机产生 2 个 Salt1 和 Salt2 ,服务器数据库里保存 Hash(Salt+Salt1+Hash(Password+Salt2))的值。
用户登录时,先输入用户名,系统会将 Salt2 发给客户端 (如果用户不存在也会发一个假 Salt2 迷惑黑客),用户输入密码后传回 Hash(Password+Salt2)到服务器,服务器 2 次加盐哈希进行比对。 如果数据库被拖库,由于没有全局盐 Salt 也无法制作彩虹表,只有数据库和程序同时被拖,并且破解程序才能制作彩虹表。 |
18
stamhe 2023-09-09 10:08:52 +08:00
有的,你需要的是叫 passkey 或者 passwordless 的概念,这个目前是国外的 fido 公司在推,google 和 apple 包括国内的飞书都接入了。但是他的方案不行,只是一个半残品,不能用于工业领域。我们目前在做自己的 passkey 和 passwordless 标准,基本是完美的。
|
19
XiiLii OP @stamhe 我也了解过 passkey ,感觉算是比较完美的方案,为什么说 fido 的方案有问题,能说下吗?您说的“我们”是指我国,还是?
|
20
stamhe 2023-09-10 16:47:43 +08:00
@XiiLii 我们公司产品。。。fido 的 passkey 不是完美的问题,是不能用于工业领域的问题,比如最简单的例子:google 和 apple 会把用户的 passkey 涉及的私钥同步到他们的云平台,例如 iCloud 和 Google Cloud 来帮助用户保管 passkey 的私钥,因为普通用户完全无法保管私钥,例如 [0xc7d603b438f53sdaasfdfdsaljkfdsbe2c8192c0588cef03b191d0932fe587c876a4e292faaf1] 让小白用户保管。。。。😢
|
21
XiiLii OP @stamhe 同步到云端确实不安全,但如果不同步到云端,一旦用户的设备丢失,那么这些用 PassKey 登录的平台就无法登录了吧,除非这些平台强制要求附加其它登录方式,比如手机、邮箱,换设备后再重新添加新设备的信息、删除旧设备。这些操作对于我们来说可能不负责,但对于普通用户可能麻烦些。如果系统能通过同步一键把这些事情都用户都处理了,确实方便些。就是不知道实际的安全性。请问你们公司是如何解决用户设备丢失的问题呢?
|