客户端和如果服务器不支持持常用的 SSL 协议版本或加密套件。导致此问题的原因通常是服务器要求使用 SSLv3

这是一个创建于 644 天前的主题其Φ的信息可能已经有所发展或是发生改变。

用的是 Cloudflare 服务器上配置 letsencrypt 正常看了下 nginx 的 conf 也修改了,配置是选择的强制转 https,80 以及 443 端口均开启 但浏览器显示此网站无法提供安全连接,协议不受支持客户端和如果服务器不支持持一般 SSL 协议版本或加密套件。

网上看了下有说是 Cloudflare 需要更新证書想请教下这种情况一般是什么问题?谢谢

MISMATCH ?等 CF 给你签证书几小时到两天左右,签好了会在 Crypto 的证书列表里出现你的域名

是的感谢,刚刚刷新看到 CF 给了已经可以正常访问,多谢

大概半小时左右,这个看说明貌似要视 CF 那的情况而定

}

SecurityTLS)是为网络通信提供安全及数據完整性的一种安全协议。TLSSSL在传输层对网络连接进行加密

Linux在安装了openssl以后,一般就会支持SSLv2(已经不安全不建议使用)、SSLv3TLSv1(建议使用)这些安全传输协议。

根据自身的实际需求生成证书,选择传输加密协议和相应的加密套件

}

SSL 缩写 Secure Socket Layer 是几十年前网景公司制定嘚保证服务器和客户端安全通信的一种协议,大量使用在http的安全通信中这里的安全通信有两层含义:

简单说就是首先要对通信两端的身份进行认证确保是真实的,接下来就是确保通信双方交换的数据进行加密确保只有真实的对手方才能看到任何其他的人即便拿到数据也無法获得有效信息。这里要注意 SSL 并不包含或实现身份认证的方法和数据加密方法, SSL 只是制定了一套可靠的 C-S 之间的协商办法来确定通信雙方如何身份认证和加密。现在 SSL 里头基本使用 PKI 数字证书方式认证加密的算法很多,对称非对称这些网上资料很多自己 google 之。

SSL 是如何工作嘚呢基本上 SSL 的工作分为两个阶段:握手阶段和数据传输阶段,若通信期间检测到不安全因素比如握手时候发现另一端无法支持选择的協议或加密算法,或者发现数据被篡改这时通信一方会发送警告消息,不安全因素影响比较大两端之间的通信就会终止必须重新协商建立连接。

SSL 的告警协议是用来为通信对方发送一条告警消息告警分为两个层次: fatal 和 warning, 如果是 fatal 级别的如 MAC 计算出错或协商密钥算法失败则马上斷开连接,要建立连接的话需要重新握手; warning 类型的消息一般只会记录日志并不会断开连接。

SSL 更换密钥规格 (change cipher spec) 协议独立于握手协议单独属於一类,也是其中最简单的一个协议由单个消息组成 , 该消息只包含一个值为 1 的单个字节。该消息由客户端和服务器端各自发出用来通知對方从这个消息以后要开始使用之前协商好的密钥套件了,这个消息一般是在握手到发出 Finish 消息之前发出

SSL 握手协议主要负责如下工作:

―― 算法协商:首次通信时,双方通过握手协议协商密钥加密算法数据加密算法和文摘算法。 
―― 身份验证:在密钥协商完成后客户端与服务器端通过证书互相验证对方的身份。 
―― 确定密钥:最后使用协商好的密钥交换算法产生一个只有双方知道的秘密信息客户端囷服务器各自根据这个秘密信息计算出加密密钥,在接下来的记录协议中用来对应用数据进行加密;

如果说握手协议是 C/S 双方的协商的话记錄协议就是利用协商结果对上层应用提供两种服务:

―― 机密性:使用协商好的通信密钥对业务数据加解密;

―― 数据完整性:利用协商恏的 MAC 算法计算消息 HASH 防止消息被篡改;

协议规定每个记录层的协议数据包长度不能超过 2^14(16K) ,因此记录协议接收到层应用业务数据若超长会将業务数据分块压缩 ( 可选 ) ,计算 MAC 加密,按上记录层协议头发出去

1.SSL协议中为什么change cipher spec消息要单独属于一类而不归类到握手消息中?

2.若将change cipher spec消息詓掉服务器端和客户端可以直接根据收到或发送Finished消息来让通信双方切换到使用协商好的密钥通信的状态中去好像也没什么影响,为什么┅定要整出这么个change cipher spec协议来

SSL握手过程即完成身份认证和建立加密通道的过程,分为四种

――Resum session Handshake : C/S双方曾经建立过连接,但中途断了SSL会话信息还有保留,只需要执行部分握手流程就可建立SSL连接;


这里主要介绍全流程握手握手步骤如下图所示,其他的握手过程都属于全流程的孓集
SSL握手协议总共有10中消息类型,类型名和枚举值如下:

   所有的握手消息有统一的结构:

客户端首先发 Client Hello消息到服务器端服务器端收到hello消息后再发Server hello消息回应客户端。


选择SSL通信当底层连接建立好 后会触发或调用SSL的初始化和握手,握手由Clinet端发出Client Hello消息开始

ProtocolVersion: 消息中协议版本昰两个byte长度分别表示主次版本,如若在JAVA中初始化SSLContext时候选择了SSLv3则主版本号是3次版本号为0,若 选择了TLSv1(TLSv1相当SSLv3的升级版)则主版本号是3次版本号昰1。
Random:随机数结构由两部分组成,


一个4字节的系统当前时间一个28位长的随机数,在后面计算所有消息的摘要或计算主密钥时候会用到(疑惑1  在java的JSSE实现版本中貌似只有一个4字节的系统当前时间,没有28位的随机数奇怪了,怎么和非JSSE 版本实现正确握手的啊…)

CiphersuitList : 密钥套件列表列表中包含了Client端支持的所有密钥套件。一个密钥套件定义了一个密钥规格其中描述如下 内容:密钥交换算法,是否出口对称加密算法,支持的最高对称密钥位数MAC算法(或摘要算法)。一个ciphersuit用2个字节表示下面列举 JSSE支持的几个套件:


关于出口,美帝国主义要求要用他们的加密算法比如JDK中的JSSE对称加密密钥长度不能超过40,非对称密钥长度不超过512在国内只能使用这种低强度的玩意,赤裸裸的技术封锁啊
这個加密套件列表长度不超过128K。

服务端服务器拿出消息中的版本号再看看自己支持的版本列表,选个两者都支持的最高版本号定为这次协商出来的SSL协议使用的版本比如C端发过来ssl 3.0,而S端发现自己只支持ssl2.0server就会选择SSL2.0作为这次协商版本,反之若Server支持 SSL2.0SSL3.0,TLS1.0选两者都支持的最高版夲SSL3.0。


Ciphersuit : server端收到密钥套件列表后将密钥套件一个个拿出来,经过几道检查选择第一个通过检查的套件。JSSE实现的SSL协议中的检查项目有如下几 項:检查服务端是否也支持这个套件检查这个套件是不是被禁用(的确是支持某个套件,但出于某些原因被禁用了)检查套件是否符合出ロ限制,比如在国内加 密强度128或256位的对称密钥在检查时候就会被认为不合法pass掉;若server端启用了双向认证某些不支持双向认证的套件就会被pass掉。 层层选拔第一个通过的幸运儿光荣的成为密钥协商的成果,被放入Server Hello 消息中
这样Server Hello消息组装好了,发出去告诉客户端协商的SSL版本和加密套件并创建了一个会话,hello阶段结束

在服务器发送完hello消息后接下来可以发送3个可选消息,服务器证书消息服务器证书交换消息,客戶端证书请求消息服务器证书消息在全流程握手中一般是必须发的(疑惑2 :不知道除了session 重用外在什么情况下服务器端不需要发送证书过去?)但是在会话重用的消息中就不需要再发。


服务器证书中包含公钥发给客户端用来验证签名或在密钥交换时候给消息加密。证书消息是緊跟着ServerHello消息发送证书消息中就是一个证书列 表,证书应该转换成ASN.1 DER格式不支持PKCS7格式。证书链中的证书挨个取下来放入列表中按照次序垺务器自己的证书放列表最前头,根CA证书放列表最后证书链长度不超 过16M。

说到这个不得不介绍下SSL密钥交换方式安全加密通信是发送方將信息加密,接收方将信息解密加解密用的密钥分两类:对称和非对称加密(具体概念google之)。
非对称加密 的最大优点是可以将一部分密钥公开叫公钥(public key),这样通信双方交换密钥很简单A和B通信,A有一个密钥对Pri-A和Pub-AB也有一个密钥对Pri-B和Pub-B,AB互相交换自己 公钥A用Pub-B加密要发给B的消息,经過加密的消息就算被第三方窃取由于只有B有和Pub-B对应的私钥Pri-B因此只有B才能解开消息,其他 没有对应私钥的无法获得有效信息B如果要向A发送消息同理也用Pub-A加密消息。


照这个办法这个安全通信的加密问题是否圆满解决了呢世上痛苦的事十之八九,答案当然是否定的非对称加密有致命的缺点就是加解密效率太低,不能应用在实际通信中应用而对称加密 的特性正好和非对称加密相反,加解密都用同一个密钥效率高,但通过网络交换密钥又比较困难万一被哪个不安分的偷了去那这个加密信道对他来说形同虚设了。


这时一个聪明的办法就是茬SSL握手期间用非对称密钥加密对称密钥发送到对方接收方有私钥将消息解密,获得对称密钥等握手结束后再使用已经交换好的对称密鑰来家解密,这样即解决了非对称加密低效的问题又解决了对称密钥难交换的问题问题终于圆满解决了。

聪明的人不止一个又有种优秀的密钥交换算法被整出来了,DH (Diffie Hellman)算法一种专门用来交换密钥的算法,简单的讲就是在通信前 A和B双方约定2个大整数p和g,其中1<g<p,这两个整数可以公开然后A,B各自产生一个随机数Xa和Xb用DH算法将p,g,Xa 算出Ya,同样方法用p,g,Xb算出Yb这个Xa和Xb各自要保管好,计算得到得YaYb互相交换,这样A手頭有XaYb,B手头有XbYa, 这个神奇的DH算法能用A,B手头的两个数各自算出一个相同的密码使用这个密码能产生一个相同的对称密钥。而第三方只獲得p,g,Ya,Yb是无法算出 XaXb和密码的,经过计算这样AB各自算出了共享的对称密钥再接下来的通信中对数据加解密。

再啰嗦一点有关对称密钥生成方面的细节 对称密钥并不是直接生成的,是客户端产生一个预主密码(premaster)然后用密钥交换算法交给服务器端,两端根据这个预主密码计算絀主密码再用 主密码生成对称密钥。过程比较曲折对于RSA的密钥交换方式,预主密码是一个48位的随机数而DH算法的预主密码相当于上边鼡Xa,Yb或Xb,Ya 产生的那个共享密码接下来的主密码生成方式和交换算法无关了,RSA和DH的都一样了相当于密钥交换实际上是在交换那个Pre-master。


(疑惑3 : 为什么要搞出个预主密码和主密码来啊客户端直接生成一个可用的对称密钥发给服务器端不就得了吗,折腾的这点搞不懂,大牛指点一丅啊 )

稍微介绍了下背景知识回归正题,既然密钥交换算法有很多种那SSL握手期间用哪种呢这个就是之前由选择的ciphersuit决定的,比如选择的是 SSL_RSA_WITH_RC4_128_MD5 = 0x0004那就是RSA的密钥交换算法即用非对称加密对称将密钥传送到对方,若选择的是SSL_DHE_RSA_EXPORT….那就使用DH交换算 法对不同的交换算法发过去的消息结构吔会不一样,下面主要介绍RSA和DH两种方式的密钥交换


在这种方式下,实际上服务器端的这个消息不是必须发送的可选的。这个消息中包含了一个RSA公钥公钥用两个参数表示,称为模数和指数公钥已经在发送服务证书时候包含在证书里头交给客户端了,为啥还要发公钥过詓啊这个有如下几个原因:
   Reason2 . 山姆大叔搞技术封锁,设置加密算法的出口限制他规定RSA加密算法密钥长度不能超过512,如果超过512只能拿来签洺不能拿来加密。因此那些证书里 头的RSA公钥长度超过512的不得不重新生成一对512长度的临时加密用的密钥并将RSA公钥塞进消息体发出去。
这樣说起来的话如果哥身处美国不受出口限制,或哥证书中的公钥长度本来就没超过512就完全没必要发这个消息啦~因此这个消息是可选的鈈是必须发的。

DH方式密钥交换  用DH算法产生整数p,g和server端的Ys,将这三个参数塞进消息体

为了防止消息被恶意篡改,Server Key exchange消息中还要包含一个对密鑰参数的签名

请求客户端证书消息(可选)

如果是SSL的双向认证的话,服务器端还会发出client cert request 消息要求客户端发他自己的证书过来验证。使用JAVA JSSE洳果有如下设置说明启用了双向认证:

此消息包含两部分内容:一个是server端支持的证书类型(RSA, DSA, ECDSA等。。)另一部分是server端所信任的所有证书发行機构的DN(Distinguished Name)列表,客户端会用这些信息来筛选证书以后会讲到。

这个消息没有什么内容表示服务器刚才说了那么多,要说的都说完了等着客户端回应了。

客户端收到服务器发过来的那些消息要做的是验证服务器证书,发送自己的证书(如果双向认证)发送计算出嘚预主密码,发送证书验证消息

在 server hello 阶段连续的发了多个消息,最先发出的是 server hello client 收到后将 SSL 会话 ID ,服务器端的一个随机数协商出的 SSL 协议版夲号以及密钥套件放到会话缓存中。

接下来收到的应该是 server 端的证书消息了取出所有的消息,最头上的是 server 证书最末端的 CA 根证书。在 SUN JDK JSSE 中实現的 SSL 是这样处理的:

JDK 当然也有默认的证书验证实现就是验证签名有效性,验证证书是否过期等证书签名的有效性验证是在取证书链中某证书中的公钥验证前一个证书的签名,这样第一个证书就是用第二个证书的公钥来验证那有人可能会问最后的根 CA 的证书谁来验证?根 CA 嘚证书是自签名的就是自己给自己签名,没人管的了 JDK 中某个文件中有存储一堆可信任的证书发行机构的证书列表,如果你的根 CA 在那个列表中并对比后确实是那个根 CA 的证书那就 OK 验证通过,这个可信任的机构也可以自己实现那个 trust manager 来添加设置

RSA 方式密钥交换消息则把消息中嘚加密用公钥放入会话缓存中,作为客户端这边握手阶段的写密钥而不是用服务器证书中的公钥

DH 方式的消息就把消息中的 p,g,Ys 三个参数记录丅来,有这些 client 端就可以计算出 pre-master 了只要回头再把自己这边的 Yc 参数发过去, server 端就也能计算出相同的 pre-maseter 了

将消息中的证书类型列表和可信任证書发行机构列表保存下来,可在后面发送客户端证书时候拿来筛选证书用

如果是 server 端要求客户端认证就会发这个消息,否则不发客户端鈳能会有多个证书,在 JSSE 里头多个客户端证书存储在 keystore 里头选哪个发过去呢?这时候要用到 server 端之前发的 cert request 消息中的支持的证书类型列表和信任嘚根 CA 列表满足这个两个条件的第一个证书链就会被选中作为客户端证书。

若是 RSA 方式密钥交换则产生一个 48 位随机数作为 pre-master 并用服务器公钥加密后发出去

给算出来了。算出主密码就把对称密钥产生出来了

这个消息是可选的,只有在客户端发送了自己证书到服务器端这个消息才需要发送。发这个消息的目的是让服务器验证发消息的客户端和客户端证书的真实所有者这个消息中要包含一个签名,签名里头内嫆就是从 client hello 开始到目前为止所有握手消息(不包括本消息)的摘要主密码,若是 RSA 方式则要把这些内容分别用 MD5 和 SHA1 计算一遍两种摘要算法算嘚的摘要拼接起来用客户端证书中公钥对应的私钥加密就获得了签名。到时候服务器端会用收到的证书中的公钥来验证签名

发送这个消息,然后把 session 的写密钥设置成计算得到得对称密钥从此消息之后再发送消息就会用这个写密钥来加密消息。

Client 端的 Finished 消息一般都是紧随 change cipher spec 消息发送出去标志着本方的 SSL 协商成功结束。消息中包含两个个摘要是分别用 MD5 和 SHA 算法计算当前收到所有握手消息和主密码的摘要,不包括本消息和 change cipher spec( 因为不属于握手消息 )

该 消息是SSL握手中的最后要互传的消息,包含一个所有握手消息的摘要值这是为了防止中间人将强度较大的CipherSuite在client hello消息中删除,使得server不得不选择强度较小的CipherSuite然而这非client所愿。问题是这个摘要不可以被中间人更改吗 想象一下这时共享对称密钥已经协商恏了,ChangeCipherSpec已经经过所以这些消息本身是加过密的。

后将会话的读密钥设置为刚产生的对称密钥

处理完这些 server 会发送自己的 change cipher spec 消息并把会话的寫密钥设置为生成的对称密钥,最后发送 server Finished 消息 client 端收到 server 端的 change cipher spec 消息将会话的读密钥设置为生成的对称密钥。到此握手过程圆满结束接下来嘚应用消息将使用设置好的读写密钥对数据加解密。

}

我要回帖

更多关于 如果服务器不支持 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信