最近突然想到一个问题,HTTPS 真的足够安全吗?在一些对安全性要求比较高的项目里,能只依赖 HTTPS 来保证数据安全吗?
我们也用过fiddler 、whistle 等代理软件,也知道要能劫持流量后能看到请求和返回的内容需要添加证书。那如果攻击者诱导用户添加了他自己搞的证书,然后通过假基站、免费 WiFi 这些进行中间人攻击,用户是不是就相当于裸奔了?
或者说诱导用户添加证书这个操作几乎不能实现?但好像不应该做这种假设?大部分用户都不知道这个证书的作用,很可能就稀里糊涂的被诱导添加了。
浏览器会提示你连接不安全,但可能会有人点高级按钮,然后继续访问。
证书能证明跟你通信的服务器真的是那个服务器,那如何证明证书真的可信呢?HTTPS 的实现是通信前,服务器给 client 返回一个证书,其中包括签发机构、证书主体(有域名,与client 请求的进行校验)、公钥等信息,签发机构相当与上一级的证书,循环验证,依赖操作系统本身自带的根证书保证证书可靠,保证跟你通信的这个服务器确实是这个服务器而不是进行中间人攻击的黑客。
那作为开发者,如何避免这种情况呢?或者如何识别出证书是假的?好像 js 没这个 api?
像最重要的支付业务,是如何处理这种情况的?
比如支付宝有对外提供的 API,他们会要求开发者提前把公钥下载到他们的服务器,开发者服务器请求支付宝服务器时就用提前下载好的公钥。
但这种情况对于使用浏览器的普通用户来说似乎不适用?如果js 脚本里也提前写个公钥,中间人攻击可以直接篡改你的内容?不对,https 的密钥协商是在握手的时候就解决的,js 控制不了。
像网页上可以进行网银转账,早期可能是要用 U 盾,还得在 U 盾输入金额啥的,U 盾生成的数字可能还带了转账人的信息,这样哪怕有中间人攻击也得把 U 盾也破解了才能转别人的号的钱。
这相当于是加了二次验证来防范。
如果只是简单的手机验证码是防不住的,验证码也会带到 https 的请求 body 里。
如果是支付宝扫码,那有客户端做校验能规避中间人攻击。
那是不是那些最敏感的操作都得加上这种二次验证?不能说 HTTPS 绝对安全,只是破解门槛比较高?