密码安全与会话安全

对于登录大家并不陌生 , 访问系统几乎都需要登录 。 因为系统也不知道是谁在访问 , 所以需要你告诉系统你是谁 , 还需要证明你真的是你 , 如何证明?给系统展示你的密码 , 因为密码只有你才拥有 , 你有这个密码 , 你就能证明你真的是你 , 这就是一个登录 。
密码安全与会话安全
文章图片
看似简单的几个步骤 , 但里面涉及的安全问题却有很多 。
密码存储安全
首先我们看关于密码存储安全的问题 。 系统服务器需要存储用户密码 , 才能在用户登录时验证密码的正确性 , 但存储就会有泄露的风险 , 比如数据库被偷 , 服务器被入侵 , 内部员工泄露数据 , 被撞库等风险 。 因此我们需要认真地考虑如何安全存储用户密码 。
我认为作为一名软件开发工程师 , 严禁明文存储密码是commonsense 。 那该如何解决不能明文存储密码的问题?也许看官你会说 , md5?没错 , md5可以 。 那么md5属于什么?它是一种单向散列算法 , 单向散列算法主要就是通过算法生成一个摘要 , 来解决密码不能明文化问题 。 比如:
md5(123456)=e10adc3949ba59abbe56e057f20f883e
这样虽然能解决密码不明文化 , 但是它还是会存在安全问题 。 因为现代计算机的计算能力实在太强了 , 一秒可以计算十亿次 , 可以通过穷举对比的方式破解密码 。 这也就是所谓的彩虹表攻击 。
解决被彩虹表攻击的问题对密码也有一定的要求 , 比如要求密码的复杂度 , 需要不同类型的字符进行组合 , 在生成摘要时加点盐来防止穷举破解密码 。 但这就安全了吗?还不够 。 一次算法远远不够满足安全要求 , 如md5(md5(md5(password+salt))) , 现在往往采用自适应的方式来存储密码 , 可以设置重复计算一万次 , 盐使用随机生成的16+位字符串 。
这种方式虽然性能不会很好 , 但对于密码生成摘要存储来说 , 性能不好往往是好事 , 毕竟用户注册或修改密码只是一次操作 , 用户是可以接受的 , 但对于黑客来说 , 这是致命的 , 黑客从原来的一秒产生几百万甚至上千万的md5值 , 变成了一秒只能产生一个 , 黑客想要破解一个密码 , 从现代的计算机算力来看 , 需要上千年的时间 。 目前推荐的使用密码存储算法已不再推荐md5了 , 推荐采用BcryptScryptpdkdf2算法 。
密码安全与会话安全
文章图片
(很多可以通过MD5/SHA值进行反向查询 , 都是已经存储了大量的彩虹表)
密码传输安全
解决了密码存储安全 , 再来看密码传输安全 。 有人会说使用https就能解决网络传输的安全问题 , 但这还是不够 。 浏览器到认证服务器之间请求可能会经过一层或多层gateway , 如nginx , zuul , springcloudgateway等 。 很多系统都是在gateway处安装证书设置https协议 , 浏览器到gateway处是加密传输的 , 但gateway到认证服务器还是http协议 。
攻击人可以在这条链路上窃取明文密码 , 那全链路https不就可以解决问题了?还不够 , 这些gateway内部都可能会接触到明文密码 , 都有密码泄露的风险 , 有些gateway不是我们负责的 , 无法保证他人会不会开个后门拿出明文密码 , 或者安全意识较低的程序员打印日志不小心把明文密码打印出来 。 那如何解决这个问题?我们可以采用浏览器传输密码之前就对密码先加密的方法 。
加密方式分为对称加密与非对称加密 。
对称加密:加密与解密用的是同一个密钥 。 如DES , AES非对称加密:加密与解密用的是不同的密钥 , 一个叫公钥 , 一个叫私钥 , 公钥加密的数据只能由对应的私钥才能解 , 如RSA 。