引言
HTTP是不安全的,我们的页面也被运营商插入过小黄图广告(数据被篡改),对于HTTP来说,再简单不过,只需要设定相应的DNS,做一个中间人攻击,再将修改后的数据返回,这一方面可能泄露用户隐私数据,同时也对我们的品牌形象产生恶劣影响。
然而,当我们切换HTTPS时候,运营商的这些小九九就施展不开了,服务端认证不通过,浏览器不会展示相应的页面数据;运营商实施搞的这一套东东也就不能在用户不知情的情况下搞起来了,解决办法是去除相应的受污染的DNS。
全球最大的成人网站PornHub,YouPorn都要全面切HTTPS了,我们还在犹豫什么了?
安全的HTTP的需求
对HTTP的安全需求:
- 加密(客户端和服务器的对话是私密的,无须担心被窃听)
- 服务端认证(客户端知道它们是在与真正的而不是伪造的服务器通信)
- 客户端认证(服务器知道它们是在与真正的而不是伪造的客户端通信)
- 完整性(客户端和服务器的数据不会被修改)
- 效率(一个运行足够快的算法,一遍低端的客户端和服务器使用)
- 普适性(基本上所有的客户端和服务器都支持这些协议)
- 管理的可扩展性(在任何地方的任何人都可以立即进行安全通信)
- 适应性(能够支持当前最知名的安全方法)
- 在社会上的可行性(满足社会的政治文化需要),要有公众受信能力
在这里面最重要的是前面几条
- 数据加密 传输内容进行混淆
- 身份验证 通信双方验证对方的身份真实性
- 数据完整性保护 检测传输的内容是否被篡改或伪造
安全HTTP的实现
加密方式的选择
共享密钥加密 对称密钥加密
共享密钥加密方式使用相同的密钥进行加密解密,通信双方都需要接收对方的加密密钥进行数据解密,这种方式在通信过程中必须交互共享的密钥,同样无法避免被网络监听泄漏密钥的问题;同时对于众多客户端的服务器来说还需要分配和管理密钥,对于客户端来说也需要管理密钥,增加设计和实现的复杂度,同时也降低了通信的效率;不用看都不靠谱。
公开密钥加密
公开密钥加密方式使用一对非对称的密钥对(私钥和公钥),不公开的作为私钥,随意分发的作为公钥;公钥和私钥都能进行数据加密和解密,公钥能解密私钥加密的数据,私钥也能解密公钥加密的数据;这样只需要一套密钥就能处理服务端和众多客户端直接的通信被网络监听泄漏密钥的问题,同时没有额外的管理成本;看起来挺合适。
没那么简单
公开密钥加密安全性高,伴随着加密方式复杂,处理速度慢的问题。如果我们的通信都是用公开密钥的方式加密,那么通信效率会很低。
HTTPS采用共享密钥加密和公开密钥加密混合的加密方式,在交换密钥对环节使用公开密钥加密方式(防止被监听泄漏密钥)加密共享的密钥,在随后的通信过程中使用共享密钥的方式使用共享的密钥进行加解密。
认证方式实现
数字证书
数字签名是附加在报文上的特殊加密校验码,可以证明是作者编写了这条报文,前提是作者才会有私钥,才能算出这些校验码。如果传输的报文被篡改,则校验码不会匹配,因为校验码只有作者保存的私钥才能产生,所以前面可以保证报文的完整性。
数字证书认证机构(Certificate Authority CA)是客户端和服务器双方都可信赖的第三方机构。
服务器的运营人员向数字证书认证机构提出证书认证申请,数字证书认证机构在判明申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书(也叫数字证书或证书)后绑定在一起。服务器将这份有数字认证机构颁发的公钥证书发总给客户端,以进行公开密钥加密方式通信。
EV SSL(Extended Validation SSL Certificate)证书是基于国际标准的认证指导方针办法的证书,通过认证的Web网站能获得更高的认可度。持有EV SSL证书的Web网站的浏览器地址栏的背景色是绿色的,同时在地址栏的左侧显示了SSL证书中记录的组织名称及办法证书的认证机构的名称。
使用OpenSSL,每个人都可以构建一套认证机构文件,同时可以用来给自己的证书请求进行签名,这种方式产生的证书称为自签名证书,这种证书通常是CA自己的证书,用户开发测试的正式,也可以像12306这样的,信不信由你。
证书信任的方式
- 操作系统和浏览器内置每个操作系统和大多数浏览器都会内置一个知名证书颁发机构的名单。因此,你也会信任操作系统及浏览器提供商提供和维护的可信任机构。受信认证机构(也有不受信的,比如赛门铁克,沃通,或者像2011年被入侵的DigiNotar等)的证书一般会被操作系统或者浏览器在发行或者发布时内置。
- 证书颁发机构CA( Certificate Authority,证书颁发机构)是被证书接受者(拥有者)和依赖证书的一方共同信任的第三方。
- 手动指定证书所有浏览器和操作系统都提供了一种手工导入信任证书的机制。至于如何获得证书和验证完整性则完全由你自己来定。
PKI(Public Key Infrastructure),即公开密钥基础设施,是国际上解决开放式互联网络信息安全需求的一套体系。PKI支持身份认证,信息传输,存储的完整性,消息传输,存储的机密性以及操作的不可否认性。
数据完整性
数字签名是只有信息发送者才能产生的别人无法伪造的一段文本,这段文本是对信息发送者发送信息真实性的一个有效证明,具有不可抵赖性。
报文的发送方从报文文本生成一个128位的散列值(或称为报文摘要活哈希值),发送方使用自己的私钥对这个摘要值进行加密来形成发送方的数字签名。然后这个数字签名将作为报文的附件一起发送给报文的接收方。报文的接收方首先从接收到的原始报文中计算出128位的散列值,再用发送方的公钥来对报文附加的数字签名进行解密。如果两次得到的结果是一致的那么接收方可以确认该数字签名是发送方的,同时确认信息是真实的 。
HTTPS数据交互过程
HTTP中没有加密机制,可以通过SSL(Secure Socket Layer 安全套接层)或TLS(Transport Layer Security 安全层传输协议)的组合使用,加密HTTP的通信内容。
HTTPS是 HTTP Secure 或 HTTP over SSL。
SSL(Security Socket Layer)是最初由网景公司(NetScape)为了保障网上交易安全而开发的协议,该协议通过加密来保护客户个人资料,通过认证和完整性检查来确保交易安全。网景公司开发过SSL3.0之前的版本;目前主导权已转移给IETF(Internet Engineering Task Force),IETF以SSL3.0为原型,标准化并制定了TSL1.0,TLS1.1,TLS1.2。但目前主流的还是SSL3.0和TSL1.0。
SSL工作在OSI七层模型中的表示层,TCP/IP 四层模型的应用层。
SSL 和 TLS 可以作为基础协议的一部分(对应用透明),也可以嵌入在特定的软件包中(比如Web服务器中的实现)。
SSL 基于TCP,SSL不是简单地单个协议,而是两层协议;SSL记录协议(SSL Record Protocol)为多种高层协议(SSL握手协议,SSL修改密码参数协议,SSL报警协议)提供基本的安全服务。HTTP是为Web客户端/服务器交互提供传输服务的,它可以在SSL的顶层运行;SSL记录协议为SSL链接提供两种服务,机密性:握手协议定义了一个共享密钥,用于SSL载荷的对称加密。 消息完整性:握手协议还定义了一个共享密钥,它用来产生一个消息认证码(Message Authentication Code,MAC)。
SSL记录协议操作
- 分段 将每个上层消息分解成不大于2^14(16384)位,然后有选择的进行压缩
- 添加MAC 在压缩数据的基础上计算MAC
- 加密 消息加上MAC用对称加密方法加密
- 添加SSL记录头 内容类型(8位),主版本(8位),副版本(8位),压缩长度(16位)
SSL握手过程
- 第一阶段 建立安全能力 包括协议版本 会话Id 密码构件 压缩方法和初始随机数
- 第二阶段 服务器发送证书 密钥交换数据和证书请求,最后发送请求-相应阶段的结束信号
- 第三阶段 如果有证书请求客户端发送此证书 之后客户端发送密钥交换数据 也可以发送证书验证消息
- 第四阶段 变更密码构件和结束握手协议
SSL协议两个重要概念,SSL会话,SSL连接;SSL连接是点到点的连接,而且每个连接都是瞬态的,每一个链接都与一个会话关联。SSL会话是一个客户端和一个服务器之间的一种关联,会话由握手协议(Handshake Protocol)创建,所有会话都定义了一组密码安全参数,这些安全参数可以在多个连接之间共享,会话可以用来避免每一个链接需要进行的代价高昂的新的安全参数协商过程。
Client Server
ClientHello:HandShake -------->
ServerHello:Handshake
Certificate*:Handshake
ServerKeyExchange*:Handshake
CertificateRequest*:Handshake
<-------- ServerHelloDone:Handshake
Certificate*:Handshake
ClientKeyExchange:Handshake
CertificateVerify*:Handshake
[ChangeCipherSpec]
Finished:Handshake -------->
[ChangeCipherSpec]
<-------- Finished:Handshake
Application Data <-------> Application Data
客户端服务器数据交互实战
使用openssl命令
openssl s_client -state -connect q.qunarzz.com:443
该命令可以显示SSL握手过程,SSL证书链,公钥证书以及其他相关的状态和属性信息。
使用Wireshark抓取数据包
相关配置
- 配置环境变量,同时保证文件路径存在
SSLKEYLOG=/path/to/sslkeylog.log
- 配置Wireshark
Wireshark->Preference->Protocols->SSL->(Pre)-Master-Secret log filename=>选择上面的路径
抓包操作
- 在命令行中打开Chrome或者Firefox,确保环境变量被读取;如果不行就用Chrome或者Firefox的开发版。
open /Applications/Firefox.app open /Applications/Google\ Chrome.app
- 确保$SSLKEYLOGFILE里面有内容了,再往下进行。
- 选择对应网卡,抓包配置为host http://q.qunarzz.com,开始抓包
- 使用刚刚打开的浏览器访问一个对应host http://q.qunarzz.com下的某个资源,在抓包界面使用ssl过滤数据
- 在抓包界面可以看到对应的SSL握手信息,同时还能看到解密后的应用数据。
内容解析(不同的网络资源可能不完全一致,比如需要客户端证书)
客户端⇒服务器
- Client Hello
- 最高支持的协议版本 如TLS 1.0
- 支持的加密算法列表(Cipher Suites)
- 支持的压缩算法列表(Compression Methods)
- 客户端生成的随机数,稍后用于生成会话密钥
服务器⇒客户端
- Server Hello
- 选定的协议版本
- 选定的加密算法
- 选定的压缩方法
- 服务端生成的随机数,稍后用于生成会话密钥
- Certificate 证书内容
- Server Key Exchange, Server Hello Done
- 公钥
- 数字签名
- Server Hello Done
客户端⇒服务器
- Client Key Exchange, Change Cipher Spec, Finished
- 公钥
- Change Cipher Spec
- Finished
客户端⇒服务器
- HTTP GET
服务端⇒客户端
- 内容的数据片段信息
- HTTP HTTP/1.1 200 OK
服务端⇒客户端
- Encrypted Alert
- Alert (Level Warning, Description: Close Notify)
参考资料
- 《Web性能权威指南》
- 《RFC 2246》
- 《图解HTTP》
- 《HTTP权威指南》
- 《HTTPS权威指南 在服务器和Web应用上部署SSL/TLS和PKI》
- 《计算机网络系统方法》
- 《计算机网络自上而下方法》
- 《计算机安全原理与实践》
- 《网络安全基础-应用与标准》
- 《PKI/CA与数字证书技术大全》
- 《SSL与TLS》
- 《OpenSSL官方命令文档》
- 《OpenSSL与网络信息安全-基础、结构和指令》
- 《OpenSSL攻略》
- Wireshark Doc SSL