用户注册密码加密和后端校验的权衡

9 篇文章 0 订阅
1 篇文章 0 订阅

背景

  1. 对于一个系统来说,显然把用户的密码明文存储是大忌,那么必然要加盐加密存储。
  2. 在登录注册过程中,密码显然不能明文传输,那么必然会用https来做登录注册接口。
  3. 但是 https 并不是绝对安全的,经常用抓包工具调试软件的就会明白,虽然条件苛刻,但是也能实现中间人攻击,那么为了安全,应该在浏览器或者客户端把密码先做加密处理(MD5),即使被中间人攻击了,也不会泄露密码。Link
  4. 那么问题来了,对于后端开发人员来说,客户端是不能被信任的,如果采用MD5或其他摘要算法,后端是无法对密码强度进行检验的,如何解决这个问题?

实验环节

为了解决这个问题,我首先对几个知名网站的注册进行抓包,看看他们是怎么处理这个问题的 (截图丢失这里暂时只放结论)
  1. 阿里云账户: https + 明文密码
  2. 微软账户: https + 明文密码
  3. 百度个人中心: https + 某种未知加密
  4. 微信公众平台: https + MD5
  5. 谷歌账户:https + 明文密码

分析思考

  1. 上述5个网站中百度的最有意思,从密文上没看出来是何种加密方法,密文长度和密码长度趋势相反,引起了我的好奇,于是提取js观察,原来用了RSA算法,这种非对称加密传输密码,确实能保证密码被可靠的传输到后端,这个过程和https传输对称加密密码过程是一样的,除非这个黑客黑到极致,不仅成功做了中间人攻击,还顺手把百度的那个js给改成了他自己的一套,用户注册的密码被中间人解密后再用真正的百度的那个js加密请求给百度后端(从这个角度考虑,只要中间人存在,就不存在绝对的安全,就算用了Hash加密密码,中间人捕获到你的md5密文,来伪造请求登录,登陆成功过后还不是可以为所欲为,如果杠精说阿里、微软谷歌的都不安全,微信公众平台和百度才叫真正的安全,那么大可怼回去,这只不过是五十步笑百步,在中间人面前,皆是蝼蚁)。
  2. https 的可靠性还是被认可的,毕竟对https进行中间人攻击,条件是很苛刻的,如果是浏览器,会给你提示证书错误,阻止你的访问,如下图。如果是自己开发的客户端,ssl证书的认证过程也是可控的。
    在这里插入图片描述
  3. 回到题目,如果使用https + 密码明文进行注册,服务端自然可以检验密码强度,除了担心安全,没什么好纠结的。
  4. 如果使用https + md5进行注册,服务端无法检验密码强度,那么能自己绕过前端验证的,必然都是搞技术的开发者或者黑客(正经人谁 TM 使 Postman 注册),黑客注册一个脆弱的账户自己用的话,其意义跟注册一个密码强度高的账户没区别,系统安全的要求都是防止恶意用户越权访问。如果黑客注册一堆脆弱的账户给别人用,其依然没意义,既然是黑客注册的,密码简单和复杂没区别,因为黑客完全掌握。因此也没什么好纠结的。
  5. 如果使用RSA非对称加密进行注册,服务端可以解密得到密码明文,从而检验密码强度,密码没有在https加密下明文传输(这话说着别扭),心理好受,又担心非对称加密代价比较大,其实注册不是一个高并发的场景,在网关层面做好防护,防止流量攻击即可。因此也没什么好纠结的。

总结起来,为了屁事少,前端做个密码强度校验,然后https请求到服务端,服务端对密码加盐增加密码长度,以sha或者md5的形式存储到数据库即可。如果你作为不受信任的服务提供商,为了充分保护用户隐私(避嫌),大可在https请求之前,做个MD5哈希,服务端不接触用户用户的明文密码,就不会有因为日志等因素泄露用户隐私的风险!

其实我有考虑能否使用同态加密,但是没研究过其可行性,只是设想客户端传输了服务端不可解的密文,服务端又能判断密码强度,然后服务端存储这个不可解的密文,这样就能做到md5形式的避嫌,又能做到不传输明文,还可以在服务端校验密码强度,全部痛点都解决了(除了开发者肝疼)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现前端密码加密后端解密,可以使用一些加密库来完成。 例如,在前端使用CryptoJS库中的AES算法对密码进行加密,然后将加密后的密码传输给后端;在后端使用相同的库对加密后的密码进行解密,获取原始密码,再与数据库中存储的密码进行比对,验证密码是否正确。 以下是一个简单的示例代码: 前端代码: ```javascript import CryptoJS from 'crypto-js' // 加密密码 function encryptPassword(password, key) { const encrypted = CryptoJS.AES.encrypt(password, key) return encrypted.toString() } // 调用示例 const password = '123456' const key = 'my-secret-key' const encryptedPassword = encryptPassword(password, key) // 将 encryptedPassword 传输给后端进行验证 ``` 后端代码: ```javascript const CryptoJS = require('crypto-js') // 解密密码 function decryptPassword(encryptedPassword, key) { const bytes = CryptoJS.AES.decrypt(encryptedPassword, key) const decryptedPassword = bytes.toString(CryptoJS.enc.Utf8) return decryptedPassword } // 调用示例 const encryptedPassword = 'U2FsdGVkX1+2MBXDnZyE1hZQbC3QFg2Jr7unJyJtYYs=' // 前端传输过来的加密后的密码 const key = 'my-secret-key' const decryptedPassword = decryptPassword(encryptedPassword, key) // 将 decryptedPassword 与数据库中的密码进行比对,验证密码是否正确 ``` 需要注意的是,加密算法的安全性与使用的加密密钥的安全性密切相关,因此在实际使用中需要选择安全可靠的加密算法和密钥。另外,还需要注意密码传输过程中的安全性,建议使用HTTPS协议传输数据以保障数据安全

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值