大家好,我是小林,昨晚有位读者又给我送素材来了。
他在面试字节,被问到这个问题:HTTPS 会加密 URL 吗?
答案是,会加密的。
因为 URL 的信息都是保存在 HTTP Header 中的,而 HTTPS 是会对 HTTP Header HTTP Body 整个加密的,所以 URL 自然是会被加密的。
下图是 HTTP/1.1 的请求头部,可以看到是包含 URL 信息的。
对应的实际的 HTTP/1.1 的请求头部:
HTTP/1.1 请求的第一行包含请求方法和路径。HTTP/2 用一系列伪头部(pseudo-header)替换了请求行,这五个伪头部很容易识别,因为它们在名称的开头用了一个冒号来表示。
比如请求方法和路径伪头字段如下:
- ":method" 伪头字段包含了 HTTP 方法;
- ":path" 伪头字段包含目标 URL 的路径和查询部分;
如下图:
上图是我浏览器 F12 开发者工具查看的信息,浏览器显示信息是已经解密后的信息,所以不要误以为 URL 没有加密。
如果你用抓包工具,抓包 HTTPS 的数据的话,你是什么都看不到的,如下图,只会显示“Application Data”,表示这是一个已经加密的 HTTP 应用数据。
HTTPS 可以看到域名吗?
再问大家一个问题,HTTPS 可以看到请求的域名吗?
从上面我们知道,HTTPS 是已经把 HTTP Header HTTP Body 整个加密的,所以我们是无法从加密的 HTTP 数据中获取请求的域名的。
但是我们可以在 TLS 握手过程中看到域名信息。
比如下图,TLS 第一次握手的 “Client Hello” 消息中,有个 server name 字段,它就是请求的域名地址。
所以,用了 HTTPS 也不能以为偷偷在公司上某 hub 不会被发现。
HTTPS 的应用数据是如何保证完整性的?
TLS 的握手协议我相信大家都很熟悉了,我也写过相关的文章了:
- HTTPS RSA 握手解析
- HTTPS ECDHE 握手解析
然后对于 HTTPS 是怎么加密 HTTP 数据的,我没有提到过。
然后很多读者以为 HTTP 数据就用对称加密密钥(TLS 握手过程中协商出来的对称加密密钥)加密后就直接发送了,然后就疑惑 HTTP 数据有没有通过摘要算法来保证完整性?
事实上,TLS 在实现上分为握手协议和记录协议两层:
- TLS 握手协议就是我们说的 TLS 四次握手的过程,负责协商加密算法和生成对称密钥,后续用此密钥来保护应用程序数据(即 HTTP 数据);
- TLS 记录协议负责保护应用程序数据并验证其完整性和来源,所以对 HTTP 数据加密是使用记录协议;
TLS 记录协议主要负责消息(HTTP 数据)的压缩,加密及数据的认证,过程如下图:
具体过程如下:
- 首先,消息被分割成多个较短的片段,然后分别对每个片段进行压缩。
- 接下来,经过压缩的片段会被加上消息认证码(MAC 值,这个是通过哈希算法生成的),这是为了保证完整性,并进行数据的认证。通过附加消息认证码的 MAC 值,可以识别出篡改。与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编码。
- 再接下来,经过压缩的片段再加上消息认证码会一起通过对称密码进行加密。
- 最后,上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的加密报文数据。
记录协议完成后,最终的加密报文数据将传递到传输控制协议 (TCP) 层进行传输。