3. 如何保证http的安全性
intro
上一篇写的真是狗烂, 完全没有自己的思考, 今天准备重写, 着重强调要去理解这件事, 我们https的存在是为了解决http明文传输的问题, 以及中间人可能会冒充收件人来修改消息的行为.
https正式通讯以后, 使用对称加密 - [第二阶段, 对称加密的正常聊天阶段]
但是对称加密的秘钥从哪儿来 - [第一阶段, 比较复杂的协商秘钥的阶段]
根本矛盾
我们设想一个场景: 现在网络中有个不诚实的路由器, 他拿到你的包以后并不是那么老实的直接转发, 而是会拆开来看看你的聊天内容, 他甚至可以改改你的包, 改改Body里的某些字段属性, 然后重新设置content-length
, 这在http协议中是无法察觉的 (或者说删掉你一个Cookie) , 这个就是我们最根本的矛盾. 如果只是删掉一些无关痛痒的内容就算了, 但如果这个http-post请求是转账的, 然后他篡改你body里写的金额内容呢?
如果会话双方互相交换秘钥呢?
我们最直观的想法是对话双方使用秘钥加密, 这样他不仅看不到, 而他一旦尝试修改, 会直接导致对面无法解密, 成为一个无效请求. 这样如何呢? 好, 现在你们准备在http连接以后发送秘钥过去, 然后接下来的内容就用这个秘钥加密. 这样做最直接的问题, 就是至少这条信息, 也就是说你们发密码也还是明文发的, 接下来如果你们尝试:
使用对称加密: 他可以捕获到这个对称秘钥, 然后拆你的包, 改字段重新封包重新加密以后发走, 可靠性零
使用非对称加密: 你把服务器公钥发给他, 他用服务器公钥加密自己的公钥, 即
hashed = server-public(client-public)
, 这样中间人能截获一个服务器公钥, 以及一个hashed.虽然中间人拿hashed没办法(因为缺少server-private), 但能拿到服务器公钥也挺不错, 至少可以打开后续通话中, 服务器用私钥加密过的, 服务器响应报文, 虽然改不了你的, 但他可以看你们聊天
另一种情况就更糟糕了, 中间人另外生成一套 fake-key, 服务器在发 server-public 的时候就改, 你拿到的是 fake-public, 你发的
hashed=fake-public(client-public)
, 他有fake-private就不仅能看, 甚至能改
我们想想, 这都造的什么孽, 无非就是因为, 你手上只能拿到一个key, 而你根本无法通过这个key判断出对面到底是谁, 你不知道这个key是中间人的还是服务器的, 这就是最根本的矛盾.
如何得知对方到底是谁
你想访问 baidu.com , 现在对面(反正也不知道是谁) 给你发了一个证书过来, 表明你看我有权威机构签发的证书因此我是baidu.com: 证书是用权威机构的私钥加密过的结构体, 而浏览器里内置了权威机构的公钥, 浏览器就用这个公钥试试, 发现真的能解开, 因此是有效证书, 于是从结构体里拿信息:
Host: 证书持有人, 上面写着百度
Server-Public: 百度的公钥
这样你就在没有发公钥的情况下, 得知了百度的公钥, 然后你用这个公钥加密一个对称秘钥发给对方, 百度用自己的私钥解开[完成步骤一], 接下来你们的对话都用这个对称秘钥进行了[完成步骤二] . 简单总结, 我们通过引入权威机构的证书, 来保证这个公钥一定是百度的, 而不是中间人的:
他把证书发给你
你打开拿到百度公钥
用百度公钥加密 [对称秘钥]
百度用百度私钥解开拿到 [对称秘钥]
Last updated
Was this helpful?