Web 应用的用户密码安全策略,大家觉得怎样的架构设计比较合适?

2019-12-12 12:06:00 +08:00
 tctc4869

目前已知的加密安全策略,有 hash 散列,对称加密,非对称加密。 密码安全这一块,那么出于使用简单考虑,优先使用 hash 散列作为密码的安全策略,可能会包括 hmac。

预防用户密码策略,除了验证码这种,在前端和后端要用哪些方式呢,

( 1 )若在前端使用 Hmac 加密,毕竟前端代码是能被看见的,即便是 C/S 客户端也有被还原出源码的可能性。在前端使用 Hmac 对密码进行 Hash 有意义吗,

( 2 )若换一种方式,在前端使用简单的 Hash,然后在后端进行二次 Hash。这个在前端抓包的那边看来不就等于相当于只用了一次对密码进行 Hash 摘要吗?

所以实际情况下,若用 Hash 散列作为密码安全的主要部分,预防彩虹表这种的话,安全策略怎样考虑比较好?要或者只能配合其他的验证手段,例如验证码?或者是配合对称加密?

2027 次点击
所在节点    程序员
12 条回复
imn1
2019-12-12 12:13:40 +08:00
加盐和 2FA 不是基础么?
验证码是防 bot 的,不是账户安全吧
xuanbg
2019-12-12 12:59:18 +08:00
担心网络传输不安全的,只需要上 HTTPS 就行,没必要复杂化。担心存储不安全的,加盐或者 RSA 加密,然后,你要担心的问题变成了盐的泄漏或者 RSA 密钥泄漏。。。

总之,不存在绝对的安全,提高攻击的成本超过攻击的收益即可。
xuanbg
2019-12-12 13:02:33 +08:00
当然,密码至少得做一次 MD5,无论是传输还是存储。知道密码的原始字符串是什么的只能是用户。
crab
2019-12-12 13:55:27 +08:00
各个大站 F12 抓包看登陆的密码字段
yyfearth
2019-12-12 15:19:13 +08:00
@xuanbg MD5 也太过时了 就连 SHA1 都不要用了 至少 SHA256 或者 SHA3 类
最好是 bcrypt PBKDF2 之类的

就 1 而言 前端加密或者 Hash 本身对密码安全性其实意义不是很不大 因为根本加密或者 Hash 后传到后端的才是真正的密码原文 如果你后端不在加密或者 Hash 处理 相对于数据库存密码原文 脱裤完蛋
就 2 而言 你说的是对的 前端发到后端的才算密码原文 所以后端必须再加密或者 HASH



理论上如果 HTTPS 够可靠 前端没必要做 HASH
但是前端做 HASH 还是有些好处的:
1. 不管用户密码多长多复杂 传到后端的密码格式长度和编码是一样的 不需要担心长度 特殊字符和编码的限制
2. 如果脱裤 增加了制作彩虹表的难度 想来直接反过来推算非常困难 因为后端输入的密码是 HASH 过的 都很长 就算是用密码原文根据前端 HASH 算法来制作 至少难度增加了不少 因为需要两次 HASH 如果前端也加盐 就更难了
3. 保护了用户密码原文 应为用户的密码原文不再通过网络传到后端 就算网络窃听或者被脱裤再彩虹表 都没办法直接拿到用户密码原文用去黑其他账户或者社工 除非也用彩虹表来撞

用 HTTPS 是必须的 否则没办法解决由证书做到的信任基础 再怎么加密都可以被监听和泄漏
后端做 HASH 是一定必要的 否则脱裤就完蛋
但是考虑到 HTTPS 也不一定保证安全的现在 前端做些 HASH 也是不错的加强
anviod
2019-12-12 15:30:00 +08:00
个人做的几个项目均是
* 前端使用服务端生产的 RSA 公钥加密明文密码
* 后端数据持久化存储密码 哈希散列 Bcrypt
* 后端收到前端密文->RSA 解密 后再进行一次 Bcrypt 方法计算
xuanbg
2019-12-12 15:33:30 +08:00
前端保存、传输密码前肯定要 HASH 的,不然明文密码总会有泄漏的风险。至于 MD5,我认为一般情况下足够了,SHA256 在密码传输和存储上也没有增加多少安全性。反正攻击者都是直接拿来用,管你是 MD5 还是 SHA256。
@yyfearth
maemual
2019-12-12 15:36:34 +08:00
传输:HTTPS
后端:bcrypt/scrypt 之类
策略:2FA
realpg
2019-12-12 16:37:30 +08:00
@xuanbg #7
前端 hash 是好习惯 但是也可能出神一般的傻逼用户坑。

我这就遇到过 用户密码是 abc post 给后端是 md5(_user-input-password_) 然后后端再 md5 之前那个 md5

然后用户反馈登录不上去

用户直接告诉你 我的密码就是 abc 我试过了 就是登录不上去

你手动去数据库验证 数据库里存的就是 md5(md5("abc"))
用户传过来的并不是 md5("abc") 但是用户坚持他输的就是 abc
xuanbg
2019-12-12 17:07:42 +08:00
@realpg 这个是前后端对密码的处理逻辑不一致的问题。这个实例里面,前端没错,后端不需要额外再 MD5 一次。当然数据库存 md5(md5("abc"))也没错,但错就错在没有把前端给的字符串 md5 一次再比较。
xuanbg
2019-12-12 17:08:55 +08:00
@xuanbg 是对密码的存储和验证处理逻辑不一致的问题
realpg
2019-12-13 11:28:36 +08:00
@xuanbg #10
你根本不理解我说的问题出在哪里。
你也没法去调试。
当你的傻逼用户多,且你的系统涉及金融等操作,可能就遇到我之前的问题。
我这个最终的原因是客户手指头太粗实际都按错了。但是客户自己岁数大眼神也不咋样根本不看那个密码加星号之前的短暂显示输入文本。

而后台调试也不能在客户不到现场的情况下,确认用户到底输入的是什么以便引导用户改正。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/628315

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX