ssl/tls是什么?是怎么工作的?

最近在思考一个关于邮箱服务器的问题,其中涉及到了SSL/TLS加密传输,于是想研究一下什么,到底是怎么实现加密的,通过查找各方面的资料,发现这个涉及到的东西还蛮多的,可以单独写一篇文章整理一下自己的理解。

SSL/TLS是什么?

SSL(安全套接字层)是一种标准安全协议,用于在在线通信中建立Web服务器和浏览器之间的加密链接。

那TLS又是什么?Transport Layer Security (TLS)是SSL协议(Secure Sockets Layer)的升级版,TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。现在习惯将这个两个组合在一起称为SSL/TLS,只要知道它是一种用于加密的安全协议就好了。

当网页期望用户提交机密数据(包括个人信息,密码或信用卡详细信息)时,网页应使用加密,这个时候web服务器就应该使用HTTPS协议来传输数据,它其实就是HTTP和SSL/TLS结合实现的;同样的还有SMTPS,它是加密的简单邮件通信协议,这样在传输邮件的时候就不是明文传输了,一般我们在设置邮箱服务器的时候可以选择是否勾选SSL/TLS的,如果没有勾选的话邮件就是明文传输了。

SSL/TLS有什么作用?

这里参考了网上的一些观点:
不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。

  • 窃听风险(eavesdropping):第三方可以获知通信内容。
  • 篡改风险(tampering):第三方可以修改通信内容。
  • 冒充风险(pretending):第三方可以冒充他人身份参与通信。

SSL/TLS协议是为了解决这三大风险而设计的,希望达到

  • 所有信息都是加密传播,第三方无法窃听。
  • 具有校验机制,一旦被篡改,通信双方会立刻发现。
  • 配备身份证书,防止身份被冒充。

SSL证书

先说明一下:SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

在讲SSL/TLS的工作流程之前,先要说明一下SSL证书这个东西,来思考一个问题:
基本思路里面的公钥加密法,如何保证公钥不被篡改?答案是:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。

那SSL证书是什么?怎么保证它是可信任的?
SSL 证书就是遵守 SSL协议,由受信任的数字证书颁发机构CA,在验证服务器身份后颁发,具有服务器身份验证和数据传输加密功能。
怎么才能申请到SSL证书?或者说影响该证书申请的因素有哪些?
影响证书的因素:申请中提到的企业/公司是否有合法身份以及申请人是否控制证书​​中提到的域名。

申请到证书的步骤是怎么样的?

  1. 制作CSR文件
    CSR就是Certificate Signing Request证书请求文件。这个文件是由申请人制作,在制作的同时,系统会产生2个密钥,一个是公钥就是这个CSR文件,另外一个是私钥,存放在服务器上。要制作CSR文件,申请人可以参考WEB SERVER的文档,一般APACHE等,使用OPENSSL命令行来生成KEY+CSR2个文件。
  2. CA认证
    域名认证,一般通过对管理员邮箱认证的方式,这种方式认证速度快,但是签发的证书中没有企业的名称;
    企业文档认证,需要提供企业的营业执照。一般需要3-5个工作日。 也有需要同时认证以上2种方式的证书,叫EV证书,这种证书可以使IE7以上的浏览器地址栏变成绿色,所以认证也最严格。
  3. 证书的安装
    在收到CA的证书后,可以将证书部署上服务器,一般APACHE文件直接将KEY+CER复制到文件上,然后修改HTTPD.CONF文件。

注意:证书分为单域证书、通配符证书、多域证书及扩展验证证书,申请证书的时候要看是申请那一类了。

证书在什么情况下被使用?是怎么使用的?

  1. 我们在点击web站点的时候,比如输入https://www.domain.com ,进行dns解析后web服务器进行响应,web服务器自动传送https://www.domain.com 网站的数字证书给用户,上文说到了,证书是安装在web服务器里面的,证书里面含有公钥,所以这里相当于服务器把公钥传递给了客户端,当然服务器那里还有自己的私钥,具体过程如下图。
  2. 客户端是使用浏览器进行操作的,不同版本的浏览器自动产生40位或128位的会话密钥,用于对交易的信息进行加密,也就是说客户向服务器索要公钥后还要与服务器协商生成一个“会话秘钥”。
    如下图,第三步获取到crt证书后,需要检验证书是否有效,如果无效则会显示警告信息,有效则生成一个随机数,即会话密钥,这个会话密钥再使用crt里面的公钥加密后传输给web服务器,服务器使用自己的私钥进行解密,获取浏览器生成的随机“会话密钥”,现在客户端服务器都知道这个“会话密钥”了,后续通信都用这个会话密钥进行加密通信了。

SSL是怎么工作的?

简单概括就是:

  1. 客户端向服务器端索要并验证公钥。
  2. 双方协商生成”对话密钥”。
  3. 双方采用”对话密钥”进行加密通信。
    具体是怎么协商生成“会话密钥”的,上文提到了,这里还有一个疑问,为什么不直接使用crt证书里面的公钥进行加密,再使用服务器里面的私钥进行解密呢?更何况服务器里面的私钥也可以进行加密,crt里面的证书再进行解密即可。
    原因为:每一次对话(session),客户端和服务器端都生成一个”会话密钥”(session key),用它来加密信息。由于”对话密钥”是对称加密,所以运算速度非常快,而服务器公钥加密是非对称加密,比较耗时间,所以证书里面的公钥只用于加密”会话密钥”本身,这样就减少了加密运算的消耗时间。

那么会话密钥和公钥有什么区别呢?

  1. 会话加密是对称加密,服务器和客户端协商后生产一个会话密钥,所以服务器和客户端是共享一个相同的密钥的,当然不是服务器和所有客户端共享一个相同的密钥,而是每个客户端都有自己的密钥,比较这个会话密钥是客户端(浏览器)随机生成的,所以服务器需要维护多个密钥。
  2. 公钥是采用的非对称加密,服务器把证书(公钥)下发给每个用户正在使用的客户端(浏览器),所以是客户端共享公钥,服务器只掌控私钥,服务端与客户端密钥是一个1对多的关系,客户端发送的加密信息只能服务端解密,安全级别也更高,但是由于非对称加密太慢了,才采用了不同客户端不同密钥的“会话密钥”来解决这个问题。

具体TLS/SSL里面涉及到的非对称加密和对称加密的区别以及算法如下图所示:

总的来说,客户端(浏览器)与web服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用”会话密钥”加密内容,会话密钥即图中的随机数。

编码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
sslCtx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_set_tlsext_servername_callback(m_sslCtx, SslServerNameCallback);
SSL_CTX_set_timeout(sslCtx, 600);

SSL *ssl = SSL_new(m_sslCtx);

int SslServerNameCallback(SSL *ssl, int *ad, void *arg)
{
if (NULL == ssl)
return SSL_TLSEXT_ERR_NOACK;

const char *tmpName = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
string servername = tmpName ? tmpName : "";
CAutoLock lock(serverSSlCtxMapLock); // 从sslSanCtxMap查找
SSL_CTX *ctx = FindSslCtx(servername.c_str(), false);
if (ctx)
{
SSL_set_SSL_CTX(ssl, ctx);
SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), SSL_CTX_get_verify_callback(ctx));
SSL_set_verify_depth(ssl, SSL_CTX_get_verify_depth(ctx));
SSL_set_options(ssl, SSL_CTX_get_options(ctx));
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_protos_advertised_cb(ctx, NextProtoCb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */

#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ctx, AlpnSelectProtoCb, NULL);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
}
return SSL_TLSEXT_ERR_OK;
}

结束语

对SSL/TLS涉及到的底层原理做了一个大概的说明,对学习过程中遇到的一些问题做了理解和解答,把一些问题理清楚后,对概念的理解就更加深刻了,比如明白了某个技术的由来背景,为什么会出现这个东西,问题的初衷是什么?怎么实现的?有哪些应用场景,如果把这些都调查清楚,那无论是对这个技术的使用还是新技术的创新都是有好处了,比只会用这个东西来做一些事情局限于表面工程要好得多,之前听大佬讲,有的人工作了6,7年,比别人刚毕业处理工作1,2年写出来的文章还要屎,听后感觉都可怕和悲哀,好好沉淀下去,打好基础,哪怕是寒冬来了也就不慌了,后续有时间再研究一下SSL证书申请的具体事宜。

nephen wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!