• 小白学习HTTPS


    如果你和我一样是HTTPS的小白的话,那就一起来学习这个吧。争取把这篇博客写好,写全面,从原理到实践再到部署。

    让我们先来模拟一个场景:当你嗨皮地敲着代码,你的老板偷偷摸摸跑到你的身边,"小X啊,公司最近准备把http转成https,看你平时挺闲的,这个任务就交给你吧!"

    HTTPS,我只知道它是一种安全的http协议,至于这个从HTTP到HTTPS的转换到底怎么搞,我还是一筹莫展。于是乎Google,百度~

    网站加密方案

    来源:http://blog.csdn.net/sunsunsun222/article/details/54136218

    目前开发的网站是普通的http网站,为了提高网站安全性,大概主要有三种方法

    1. 应用自行对传递的数据进行加密处理

    优点:灵活性非常高
    缺点:上传下载的流数据没法在浏览器中进行干扰(除非使用flash等插件,这里主要指用form提交下载数据),所以无法保证这种数据的安全。提高了系统复杂度。

    2.使用VPN保证数据安全

    优点:本人认为这是最安全的方式,速度快
    缺点:要求所有访问系统的人必须进行VPN连接,对用户量大的系统非常不方便

    3.使用 https 代理

    优点: 无需改造现有Web系统,只需要在Web应用和用户之间加一层https代理,实现简单,安全性很高
    缺点: 正规机构颁发的https证书是要钱的,使用自签发证书浏览器会有安全提示,而且确实有可能被第三方伪造而用户无法识别,
    但个人认为如果直接使用ip访问而不用域名访问应该没什么大问题

    HTTPS原理

    HTTPS是从HTTP演变而来的,不搞清楚HTTP就上HTTPS有点说不过去。你得知道HTTP有啥缺点,才知道为什么要用HTTPS。

    HTTP就是我们平常浏览网页时所使用的一种协议。HTTP传输的数据一般都是没有经过加密的,也就是明文的,当你用过抓包工具之后你就马上明白这个缺陷有多么可怕。总是就是,HTTP用来传输隐私信息十分的不安全。对付不安全的方式最简单的就是进行加密。

    更进一步看一下为啥要改造成HTTPS:

    来源:HTTPS 改造初探

    决定要进行 HTTPS 改造并非一时之兴致,而是出于对现状的考虑。

    一方面,在当前的网络环境下,一些问题正变得越来越突出:

    运营商劫持插入广告的情况越来越严重,极度影响微店的产品品牌与用户体验
    HTTP 采用明文传输,中间者借此盗取信息、篡改请求,用户隐私和安全无法保障
    另一方面,HTTPS 化是未来的技术趋势。

    在可见的未来,HTTP2 只在 HTTPS 环境下被支持
    iOS9 要求应用程序必须采用 HTTPS 传输
    我们看到,过去的一年中,HTTPS 化正逐渐被国内互联网公司所重视起来:

    阿里巴巴,去年双11前实现了全站HTTPS
    百度搜索,去年3月实现了全站HTTPS
    豆瓣、知乎等社交网站,也实现了全站 HTTPS

    后面会学习一下加密。

    那么为了解决这种问题,网景公司就设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而诞生了HTTPS。

    SSL在后来升级成了TLS(Transport Layer Security),实际上现在我们常用的都是TLS协议,由于SSL出现的时间比较早,并且仍然被现在的浏览器所支持,因此SSL依然是HTTPS的代名词。

    插一句话,网景这个公司有很多技术都是走在时代的前沿,但是最终还是被微软打垮了,哎。垄断就是牛逼。

    HTTPS安全么?

    举一个例子,你就相信HTTPS确实安全。目前用户只要登录Goolge账号,之后所有的搜索操作都将使用TLS协议加密。

    HTTPS的工作原理

    HTTPS在传输数据之前需要客户端和服务器进行一次握手,在握手的过程中将确立双方加密传输数据的密码信息。

    TLS/SSL协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。

    TCP三次握手协议

    为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

    image

    图片来自:http://blog.csdn.net/whuslei/article/details/6667471

    在Google Groups的TopLanguage中看到一帖讨论TCP“三次握手”觉得很有意思。贴主提出“TCP建立连接为什么是三次握手?”的问题,在众多回复中,有一条回复写道:“这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了. 因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了.”。这可视为对“三次握手”目的的另一种解答思路。

    谢希仁书中的讲解:

    “已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”

    结论:三次握手是不可靠信道的最少次数。

    HTTP握手协议

    HTTP协议和TCP协议三次握手的关系?

    可以说没有关系。
    http是应用层协议,它的任务是与服务器交换信息。至于怎么连到服务器,怎么保证数据正确,http不管。事实上它总是假设数据是正确地传输的。
    而tcp的任务是保证连接的可靠,包括防丢、防错。为了做到这些,在初次连接时要进行3次握手,以保证确实连接到了目标机器。而连接上后具体传送什么数据,tcp是不管的。
    别的应用层协议也能通过tcp进行,那么这种协议在底层也进行3次握手。
    在某些情况下,http可以不通过tcp实现,那就不需要3次握手。
    比如,我做了一把遥控咖啡壶,遥控器和壶通过红外直接连接,通过http协议post提交煮咖啡的指令,get获取是否已经煮好。http字符直接调制到红外上,此时http应用层下面直接是物理层,当然不存在3次握手了,连ip地址和mac地址也不存在。

    作者:高飞车
    链接:https://www.zhihu.com/question/52991675/answer/133095315
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
    HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
    1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。

    2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

    由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常 的做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道 客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

    握手过程的描述

    以下来自果壳:https://www.guokr.com/post/114121/

    1. 浏览器将自己支持的一套加密规则发送给网站。

    2. 网站从中选出一组加密算法和HASH算法,并将自己的身份信息以证书的形式发回给浏览器。

    证书中包含了网站地址,加密公钥,以及证书的颁发机构等信息。

    3. 获得网站证书之后浏览器要做以下工作:

    (a)验证证书的合法性(颁发证书的机构是否合法,证书中包含的网址地址是否与正在访问的地址一致等),如果证书受到信任,则浏览器里面会显示一个小锁头,否则会给出证书不受信的提示。

    (b)如果证书受信任,或者用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中的公钥加密。

    (c)使用约定好的HASH计算握手信息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。

    4. 网站接受浏览器发送来的数据之后要做一下操作:

    (a)使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手信息,并验证HASH是否与浏览器发来的一致。

    (b)使用密码加密一段握手信息,发送给浏览器。

    5. 浏览器解密并计算握手消息的HASH,如果与服务器端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

    image

    image

    这里浏览器与网站相互发送加密的握手信息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正的数据传输做一次测试。

    另外HTTP一般使用的加密与HASH算法如下:

    非对称加密算法:RSA,DSA/DSS

    对称加密算法:AES,RC4,3DES

    HASH算法:MD5,SHA1,SHA256

    其中的非对称加密算法用于在握手过程正加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。

    由于浏览器生成密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其进行加密。非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站会非常小心的保管自己的私钥,防止泄露。

    TLS握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输。正是由于HTTPS非常的安全,攻击者无法从中找到下手的地方,于是更多的采用了假证书的手法来欺骗客户端,从而获取明文信息,但是这些手段都可以被识别出来。

    HTTPS会比HTTP多消耗多少资源

    作者:牟旭东
    链接:https://www.zhihu.com/question/21518760/answer/19698894
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    https其实就是建构在SSL/TLS之上的 http协议,所以要比较https比http多用多少服务器资源,主要看SSL/TLS本身消耗多少服务器资源。http使用TCP 三次握手建立连接,客户端和服务器需要交换3个包,https除了 TCP 的三个包,还要加上 ssl握手需要的9个包,所以一共是12个包。http 建立连接,按照下面链接中针对Computer Science House的测试,是114毫秒;https建立连接,耗费436毫秒。ssl 部分花费322毫秒,包括网络延时和ssl 本身加解密的开销(服务器根据客户端的信息确定是否需要生成新的主密钥;服务器回复该主密钥,并返回给客户端一个用主密钥认证的信息;服务器向客户端请求数字签名和公开密钥)。SSL handshake latency and HTTPS optimizations. :: semicomplete.com当SSL 连接建立后,之后的加密方式就变成了3DES等对于 CPU 负荷较轻的对称加密方式。相对前面 SSL 建立连接时的非对称加密方式,对称加密方式对 CPU 的负荷基本可以忽略不记,所以问题就来了,如果频繁的重建 ssl 的session,对于服务器性能的影响将会是致命的,尽管打开https 保活可以缓解单个连接的性能问题,但是对于并发访问用户数极多的大型网站,基于负荷分担的独立的SSL termination proxy就显得必不可少了,Web 服务放在SSL termination proxy之后。SSL termination proxy既可以是基于硬件的,譬如F5;也可以是基于软件的,譬如维基百科用到的就是 Nginx。那采用 https 后,到底会多用多少服务器资源,2010年1月 Gmail切换到完全使用 https, 前端处理 SSL 机器的CPU 负荷增加不超过1%,每个连接的内存消耗少于20KB,网络流量增加少于2%。由于 Gmail 应该是使用N台服务器分布式处理,所以CPU 负荷的数据并不具有太多的参考意义,每个连接内存消耗和网络流量数据有参考意义。这篇文章中还列出了单核每秒大概处理1500次握手(针对1024-bit 的 RSA),这个数据很有参考意义,具体信息来源的英文网址:ImperialViolet。

    SSL/TLS现在已知的漏洞有哪些

    Heartbleed这个被称作史上最大的网络安全漏洞,想必很多人都有所耳闻,Heartbleed之所以能够出现,其实和我们这个问题关系还不小,前面我们谈到了频繁重建 SSL/TLS的session对于服务器影响是致命的,所以聪明的RFC 在2012年提出了 RFC6520 TLS 的心跳扩展。这个协议本身是简单和完美的,通过在客户端和服务器之间来回发送心跳的请求和应答,保活 TLS session,减少重建 TLS的session的性能开销。令人遗憾的是,openssl 在实现这个心跳扩展时,犯了一个低级的错误,没有对收到的心跳请求进行长度检查,直接根据心跳请求长度拷贝数据区,导致简单的心跳应答中可能包含了服务器端的核心数据区内容,用户名,密码,信用卡信息,甚至服务器的私有密钥都有可能泄露。心因为心跳保活的这个 BUG 在滴血,这个名字起的极度形象。

    证书伪造

    不过2010年还是有安全专家发现了TLS 1.0协议处理的一个漏洞:http://www.theregister.co.uk/2011/09/19/beast_exploits_paypal_ssl/,

    实际上这种称为BEAST的攻击方式早在2002年就已经被安全专家发现,只是没有公开而已。目前微软和Google已经对此漏洞进行了修复。

    见:http://support.microsoft.com/kb/2643584/en-us

    https://src.chromium.org/viewvc/chrome?view=rev&revision=90643

    HTTP改造为HTTPS思路

    https是由服务器,浏览器来实现的传输层加密,不需要特意的编码。。。平时怎么编写代码,在HTTPS中还是怎么写。

    很可能要问,为什么我的站点使用了https之后,用firebug之类的软件查看值提交的时候,还是会显示明文呢?例如,博客园的登陆界面提交。

    为什么这里还是能看到明文的用户名和密码呢?

    原因是因为:https(ssl)的加密是发生在应用层与传输层之间,所以,在传输层看到的数据才是经过加密的,而我们捕捉到的http post的,是应用层的,是还没经过加密的数据。

    加密的数据只有客户端和服务器端才能得到明文 客户端到服务端的通信是安全的

    支付宝也是https的,但是他的同时也增加了安全控件来保护密码, 以前认为这个只是用来防键盘监听的,其实,看下面http post截获的密码:这个安全控件把给request的密码也先加了密,紧接着https再加次密,果然是和钱打交道的,安全级别高多了:)

    image

    今年的3月开始,我们启动了 HTTPS 改造项目,并首先在微店买买和交易下单两个业务上进行试点。

    HTTPS改造可以先对部分模块进行试点改造,避免改造不当网站大面积崩坍。

    简易版改造方案:

    openssl+nginx

    第一步,使用openssl 制作秘钥和证书
    openssl下载地址 : http://slproweb.com/products/Win32OpenSSL.html
    通过命令行运行如下命令:
    创建秘钥(文件里面包含公钥和私钥):

    openssl genrsa -des3 -out server.key 1024

    创建签名请求的证书:

    openssl req -new -key server.key -out server.csr
    提取私钥:

    openssl rsa -in server.key.org -out server_private.key
    生成证书:

    openssl x509 -req -days 3650 -in server.csr -signkey server_private.key -out server.crt

    第二步,https代理服务器使用nginx就可以(nginx 真是个负载均衡,反向代理,集群的无上法宝啊~~~,在这里十分感谢nginx开发们),nginx 配置如下

    Mixed Content
    在浏览器中,我们将在 HTTPS 网页中所加载的 HTTP 资源称之为 Mixed Content。W3C 规范 将 Mixed Content 分成两类,Optionally-blockable Content 和 Blockable Content。

    Optionally-blockable Content 是指那些危险较小,即使被中间人篡改也无大碍的资源。现代浏览器默认会加载这类资源,同时在控制台打印出警告信息。

    Blockable Content 如果被中间人篡改,则会引发安全问题,浏览器必须禁止加载这类资源。在现代浏览器中,HTTPS 页面中的 JavaScript、CSS、XHR、Font、Iframe 等 HTTP 资源,都会被禁止加载,并直接在控制台打印错误信息。

    有很大一部分内容来自于这里:https://segmentfault.com/a/1190000005950801,强烈建议移步这里

    改造方案:

    了解什么是 HTTPS,什么是 Mixed Content,是我们设计技术方案的基础。下面我主要分为后端、前端(Web 与 APP)、运维三部分来说明 HTTPS 改造的技术方案。

    后端改造

    在进行 HTTPS 改造之前,我们每个后端业务独立拥有一套域名。此次 HTTPS 改造,引入了 VAP(vdian API Platform) 作为前后端的统一接入层。引入 VAP 之后:

    • 后端业务系统通过 VAP 对外提供 HTTPS/HTTP 形式的接口服务,后端业务系统与 VAP 之间通过 Dubbo/HTTP 通讯。所有接口,都在 VAP 中进行统一管理和监控,提升整体技术架构的健壮性。
    • 前端应用(Web、IOS、Android)直接向 VAP 调用服务接口,高度统一了前后端通讯机制。
    • 所有线上接口都收敛至 vap.gw.weidian.com 域名和对应集群,降低了运维成本。

    image

    前端改造
    从前端角度看,首先需要支持域名的 HTTPS/HTTP 双协议访问。为了让 HTTPS 改造更加规范,前端升级了前端发布系统,并进行域名收敛:

    前端动态内容统一到 h5.weidian.com
    静态资源CDN统一到 assets.geilicdn.com
    图片CDN统一到 wd.geilicdn.com
    后端接口统一到 VAP系统 vap.gw.weidian.com
    域名的收敛,一方面简化了技术架构的复杂度,另一方面是出于性能考虑。在 HTTPS 场景下,多域名带来更多的 TLS 握手,会降低服务端和客户端的性能。通过域名收敛,并发挥 HTTP2/SPDY 的多路复用,能在减少 TLS 握手的同时,提升网络资源的并行下载能力,一举两得。

    在代码改造上,主要分为三个场景:

    如果当前资源或页面跳转只支持 HTTP 或 HTTPS 协议,则使用支持的协议
    如果当前资源同时 HTTP 和 HTTPS 协议,需自动适配
    静态资源的URL,采用 // 引用资源,表示遵从当前页面的协议,浏览器会进行自动补全。
    动态数据中的URL,根据发起请求的协议,返回数据中的URL自动补全为请求时的协议。比如当以 HTTPS 方式发起请求,则返回的图片地址是 HTTPS 起始的,同理,如果以 HTTP 方式发起,则图片地址是 HTTP 的。

    运维配置
    运维同学的工作,一是购买 HTTPS 证书,二是配置服务器环境。在 HTTPS 配置上,除了关注本身的可用性,也需要留意性能和安全。

    在 HTTPS 性能上,我们做了几个优化:

    开启 SPDY 和 HTTP2 支持,借助多路复用提升传输性能。
    开启会话复用,减少 TLS 握手的时间与性能消耗。
    开启 HSTS,强制 HTTPS 访问,减少与服务端的交互。
    配置完整的证书链,离线完成证书的链式认证。
    开启 OCSP stapling,离线完成证书在线状态检测。
    在 HTTPS 安全上,需要注意:

    避免使用 SSL,并优先使用最新的 TLS 1.2 协议
    选择强加密的加密套件,选择支持前向安全性的加密套件
    如果你对自己的配置不太放心,可以到 ssllabs 对当前网站的 HTTPS 配置进行检测和评分,以下是我们四个域名的 HTTPS 评分。

    http网站转换成https网站之后遇到的问题

    如果是整站都是https,那么会显得网页有些慢,如果是个别页面采用https,那么如何保证从https转换到http的时候的url的准确性呢?

    比如我们用http的时候,网站的头部底部都是用的相对路径,假如你的页面是 http://aa/index.aspx  你跳转到 https://aa/login.aspx 这里怎么来跳转?只能把超链接写死

    登陆  但是这样的话,你跳转过去之后的页面 ,所有的相对路径都变成了https开头了,这样很影响网站的效率。

    虽然使用绝对地址可以解决,但是那样显然不好移植。

    稳定性问题

    出于升级过程中的稳定性考虑,需要保证 HTTPS/HTTP 两套逻辑同时在线上保持可用。一旦 HTTPS 环境下出现不可解决的问题,能够快速降级到 HTTP。

    小流量方案。对于重要业务,采用小流量的方案,逐步将 HTTP 流量引导成 HTTPS 流量。一旦出现问题,直接将 HTTP 流量切换 100%,就能快速降级。

    快速切换开关。APP 通过下发配置项,能实时控制 APP 采用 HTTPS 或者 HTTP 协议;对于 H5 来说,则是通过运维修改 nginx 配置,返回 302 重定向,来实现全站流量的降级或升级。

    HTTP改造收获

    经过此次 HTTPS 改造,我们的收获是

    解决运营商内容劫持和中间人劫持的问题,提升用户体验,保障用户的通讯安全。
    积累出前后端一整套的 HTTPS 化解决方案,让新业务和现有业务快速支持 HTTPS。
    前后端统一接入层 VAP 的引入,让整体技术架构拥有更好的扩展性。
    目前遇上的一些挑战和规划:

    域名劫持问题。在上线 HTTPS 后,我们发现在部分区域存在运营商域名劫持的情况。短期内我们是通过协议降级和运营商投诉进行了解决;长期来说,则会通过HTTPDNS和运维能力的提升,优先去规避域名劫持,其次是提升快速发现和响应的能力。
    全站 HTTPS 改造的落地。计划在8月底,让线上的原有业务和新业务全部走 HTTPS 流量。然后再稳定一段时间后,我们的开发和测试环境将只采用 HTTPS ,不再支持 HTTP。
    VAP 后续会持续提升稳定性、性能、安全性、易用性等方面,发挥出更大的技术价值。
    性能优化的最佳实践。随着移动端对 SPDY 和 HTTP2 的支持度越来越高,客户端在网络请求并发上拥有更大的优势,我们将持续做一些小实验与观察,以沉淀出性能的最佳实践方案。下图是我们现有的性能数据情况,可以看到仍然存在很大的优化空间。

    最后再总结一句,HTTPS改造既是一个很大的技术挑战,同时也是一个很好的机会。借助这个机会,让我们能及时还清技术债务,使技术架构更加清晰和明朗,来更快速地支持业务的飞速发展。如果你对 HTTPS 有兴趣,或者有独到的见解和建议。

    延伸阅读:我以为上面的知识就够用了,可以来指导一下HTTPS的改造,没想到看了下面的内容又出了一身冷汗,活到老学到老。

    HTTPS的那些坑

    HSTS


    如果一个网站既提供了HTTP服务,又提供了HTTPs服务(在过渡期通常如此),怎样引导用户访问HTTPs的站点呢?这就是HSTS(HTTP Strict Transport Security)的作用。通过Web服务器上的设置,在收到HTTP访问请求时,返回的header里带有Strict-Transport-Security字段,告知浏览器必须使用HTTPs进行访问。
    但是,HSTS并不能避免首次跳转时遇到的劫持。要彻底解决这个问题,可以申请加入Preload List(预加载列表)。
    Preload List是由Google Chrome维护的“HTTPs站点列表”,Chrome, Firefox, Safari, Edge, IE 11均在使用。一旦浏览器发现要访问的站点在Preload List上,默认就会发起HTTPs链接。这样,就避免了HSTS的首次跳转被劫持的隐患。

    SSL卸载


    通常的方案里,HTTPs的加密传输只限于客户端出发的公网阶段,在内网的通讯流量仍然采用非加密的HTTP传输。这种“把加密流量转换为非加密流量”的过程,就是常说的SSL/TLS卸载(Offloading,以下简称“SSL卸载”)。
    有一些公司会采用F5来做负载均衡,F5应付单纯的L4和L7的流量是没有问题的,但进行SSL卸载时性能往往会急剧降低,F5可以提供专门的加速卡来解决这个问题,但价格不便宜。所以,还需要专门环节来进行SSL卸载,常见的Nginx和HAProxy都可以执行这个任务。
    2010年Intel出品的Westmere系列处理器之后,CPU支持AES-NI(Advanced Encryption Standard New Instructions)指令集,可以极大提高软件进行SSL加解密的速度(通常的数据是5倍左右)。但是,单纯采用CPU并不会直接享受这种好处,还需要对应的OpenSSL提供支持。想要知道自己的OpenSSL是否利用了AES-NI加速,可以用OpenSSL的命令行调试,加上-evp参数,测试速度是否有明显变化即可。

    客户端证书


    HTTP的服务是很好验证的。一般来说,无论客户端是浏览器,还是其它工具,还是程序代码,同样的行为,结果都是相同的。所以只要一种客户端验证通过,基本就可以认为这个服务是没有问题的。HTTPs的站点则不是如此。
    与HTTP不同,HTTPs的连接建立是需要进行证书验证的,一定要从根证书开始形成完整的信任链条,连接才可以建立成功。然而,浏览器、普通工具、程序类库,它们所信任的根证书在管理上是互相独立的。比如,与浏览器不同的是,C#信任的根证书在local machine store或者current user store中,Java信任的根证书在JDK安装目录下的cacerts目录中,iOS和Android的证书管理又有不同。好在厂商一般都提供了非常详细的说明,仔细阅读即可。
    因为浏览器的证书在使用中又可以持续更新,用户往往感知不到,如果“想当然”认为浏览器验证通过就万事大吉,很可能会出问题。比如国内有不少网站使用WoSign签发的证书,但老版本的JDK并不信任WoSign的根证书,用浏览器浏览没问题的网站,程序就会报错,除非手动导入证书。Android的信任列表是随固件更新而更新的,4.2以后才内置WoSign的信任。因为WoSign行为不端,前几天Firefox, Chrome, Safari等主流浏览器又取消了对它的信任,也就意味着WoSign证书有安全风险,所以已经内置WoSign根证书的程序也应当做对应的设置。

    服务器端证书


    还是上面的现象:用浏览器验证没有问题的HTTPs站点,用程序访问就有问题。这是为什么?
    在服务器上证书配置错误,只有最终证书,而缺少中级证书的情况,我见过几次了。通常,最终证书里包含了中级证书相关的信息,所以如果缺少中级证书,浏览器为了建立证书链,会做一次耗时的操作来获取中级证书,而且这一切都发生在HTTPs连接真正建立之前。更糟糕的是,不少浏览器为了“表现更好”,会想办法绕过这个问题。所以缺少中级证书的情况一直存在,一直不会被发现,而程序调用的速度总是上不去,甚至有一定几率报错(我就遇到过这个诡异的问题)。
    如果把证书链配置完全,还要注意证书链的大小。有一些网站的完整证书异乎寻常地大,达到若干kb甚至几十kb,也就是说,在建立连接之前,就必须先传输这么多的数据。如果做单纯的PC网页浏览,或许不会有问题。但对于移动端和程序调用来说,这就是一场灾难。最好的办法,是用OpenSSL配合WireShark之类的工具,自己动手来测试。如果你熟悉TCP相关的知识,往往可以得到更好的优化方案。
    OCSP和CRL也不可忽略。这两项技术用来保证撤回证书(让证书失效)的有效性。如果你仔细观察,会发现证书里都指定了对应的OCSP或者CRL的URL,用来检查证书是否失效。按道理说,在每次建立HTTPs连接时,都应当进行OCSP或CRL检查。返回结果通常在1k左右,如果请求非常频繁,这个因素也应当考虑。

    SNI


    大家都熟悉“虚拟主机”的概念,它可以让多个域名对应到同一个IP,让同一台服务器服务多个站点。在HTTP时代,可以在header中通过host来指定需要访问的域名,一切看起来都那么完美。
    但是在HTTPs时代,却没有这样的好事,传统的HTTPs服务很难让多个域名对应到同一个IP。在进行到HTTP通讯之前,必须先建立验证证书建立连接。如果一个IP上绑定了多个域名,这个阶段服务器根本没法知道请求对应的是哪个域名,无疑会造成极大的不便。
    为了解决这种问题,SNI(Server Name Identification)应运而生了。这种技术说起来复杂,大家可以把它简单理解为“建立SSL/TLS通讯时的host header”,这样就解决了一个IP只能配单张证书的问题。
    然而SNI的诞生历史并不长,许多客户端的支持都存在奇怪的问题。比如JDK7支持SNI,但是JDK8的支持又有bug。而且这种支持往往需要调用原生的API才可以实现,Resteasy之类的类库并不支持。如果对SNI的支持有问题,即便配置正确也可能无法建立连接,因为服务端并不能识别此请求需要的证书。

    CDN


    CDN已经是业界流行的技术了,对稍微大一点的网站来说,没有CDN几乎是不可想象的。HTTP时代的CDN方案相当成熟,HTTPs的情况则不是如此。
    要使用HTTPs的CDN服务,就要决定是否将证书交给CDN提供商。基于中国目前的商业信誉水平,把证书交给CDN提供商的风险不可不考虑。恶意揣测,别有用心的人一旦拿到证书,可以很方便地通过DNS劫持发起中间人攻击,而完全不被感知到。
    另外,HTTP时代大家都喜欢将资源分散到多个不同的域名,因为建立连接的成本很低,而同一个域名的并发连接数有限。在HTTPs环境下,每次建立连接的成本高了很多,频繁下载和验证证书对移动设备和移动网络影响很大(尤其是证书很大的情况)。如果域名非常分散,影响就更加显著。所以在HTTPs时代,把域名收缩集中反而是更好的办法。

    内容及其它


    因为HTTPs的内容中无法引用HTTP的资源,所以应当保证网页中资源文件的链接都是HTTPs的。遗留的许多系统很可能并不注意这些事情,资源都采用绝对地址的形式,这样改起来工作量很大。如果要修改,最好一步到位,直接改成“协议相对URL”。
    绝对地址URL:http://www.a.com/b.css
    协议相对URL://www.a.com/b.css
    这样浏览器就可以根据当前的协议,自动生成资源的绝对地址,无论是HTTP还是HTTPs,都可以自由切换。
    如果资源都是自有的,切换HTTPs就相对容易。如果存在外部,尤其是UGC的资源,切换到HTTPs就很麻烦。如果是超链接,通常采用专门的跳转服务,也就是下面这样:
    https://link.my.com/target=www.you.com
    如果是图片这类资源,可以设定专门的程序将其抓取过来存放在自己的服务器上,再将地址替换掉即可。但是,这样做很可能要自己承担流量压力,同时还要承担恶意程序攻击的风险。
    如果是视频、游戏等富文本、交互复杂的资源,如果源站没有提供HTTPs的服务,多半只能忍痛割爱,放弃内嵌展现的形式了。

    最后再补充两点经验:


    如果真的决定上HTTPs,最好有个人把OpenSSL玩熟,否则很多问题会让你摸不着头脑,OpenSSL是很好的调试工具,很方便定位问题。
    HTTPs能解决运营商内容劫持的问题,如果是DNS劫持,要不要抱着“吾与汝偕亡”的态度上HTTPs,需要慎重考虑,我知道不少网站是HTTP与HTTPs可以随时切换的,进可攻,退可守。

    作者:helloworlds
    链接:https://www.zhihu.com/question/40288863/answer/85871126
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    前端的最大工作量是为了适配和兼容多协议(HTTPS/HTTP)而进行的资源地址改造。因为主页为HTTPS时,加载页面所需要的资源都应该支持HTTPS(否则会出现安全风险),这就要求以前只支持HTTP协议的资源同时支持HTTPS,资源越多,改造的工作量越大,越复杂。假如资源只涉及到一两个域名,改起来还比较方便,但考虑到有些资源可能是合作站点,甚至是政府部门时,这个改造可能就比较艰难。当然也会有一些比较奇葩的情况,比如有一些资源地址是写死到HTML里的,有一些是写死在数据库里的,改起来会稍微麻烦点。这就提醒广大前端,尽量考虑到协议兼容和适配,毕竟HTTPS是大势所趋。

    前端遇到的最大问题是域名收敛和连接复用。基本上大型网站在HTTP1.1/1.0协议时为了优化访问速度都会做大量的的域名分片和资源合并(比如图片和CSS),但域名分片技术在HTTPS时反而会降低速度,因为HTTPS的握手非常耗费时间。多一个域名意味着多几个HTTPS握手。另外HTTP2和SPDY都有连接复用的特性,资源合并也显得有些多余,把简单的工作复杂化。因此前端进行收敛域名既能减少HTTPS握手又能提升连接复用率,提升页面加载速度。

    可以参考但不要完全相信证书检测机构的数据。比如qualys ssl lab。它对证书的检测非常严格非常安全非常理想,导致它的数据有点不切实际。为什么?因为客户端和浏览器的更新赶不上安全技术的发展。比如IE6只支持SSLv3,比如一些客户端只支持aes cbc和rc4。但这些协议和加密算法事实上都不安全了,那网站应该怎么办?特别是在中国市场,你是升级使用最新的协议和加密算法从而导致这些用户不能访问HTTPS呢?(相当于放弃这些客户端和用户 ,比如IE6,7),还是采取折中妥协的办法,使用稍微弱一点的有安全风险的算法,但能够保证用户访问呢?比如SSL3用户只能使用RC4算法。有一些网站就会选择后者,比如google,比如百度,他们在qualys ssl lab的评级都不高。

    解决SNI的问题只能依靠多域名证书,也就是把所有需要支持到的域名绑定到一张证书上。由于所有系统都支持多域名和泛域名证书,所以里不存在系统兼容性问题,但这样会存在证书申请和维护的问题,因为一旦域名有新增,就需要重新申请一张全新的多域名证书,并且进行全量部署,成本比较大。但要想从SNI的角度解决这个问题,没有完美的解决方案。因为这依赖于客户端的SSL库是否支持SNI,作为网站或者内容提供方,即使是自有APP都控制不了是否使用SNI,更别提传统浏览器了。不管怎么样,网站服务商肯定需要支持SNI。

    查看浏览器是否支持某些特性可以使用这个网站:Can I use... Support tables for HTML5, CSS3, etc。比如SNI,SPDY等。

    java项目http变更https

    那我们的tomcat应该如何配置来改造成为HTTPS呢?

  • 相关阅读:
    LeetCode(123) Best Time to Buy and Sell Stock III
    LeetCode(122) Best Time to Buy and Sell Stock II
    LeetCode(147) Insertion Sort List
    360兼容模式不支持hidden属性的问题
    第一个博客,用来勉励自己,加油
    【LGR-059】洛谷7月月赛题解
    Codechef July Challenge 2019 Division 1题解
    AtCoder Grand Contest 035
    Comet OJ
    2019-7-3 感记
  • 原文地址:https://www.cnblogs.com/tuhooo/p/7890411.html
Copyright © 2020-2023  润新知