TLS, SSL以及周边概念

原文: tylerlong.me

created on 2011-08-21 23:59:26 | updated on 2012-03-03 23:36:28

TLS, SSL以及周边概念

这个概念听了无数遍, 很多软件安装的时候也会让你选是否安装ssl模块, 比如apache和nginx. 但是自己始终没有把这个东西彻底搞清楚. 尤其是有一些相关联的擦边概念混在一起, 更是一团乱糟糟. 比如证书, 授权, 加密, 公钥, 私钥等等.

大前提:
  1. 理想状况是公钥和私钥都是被妥善保管的, 没有泄露给任何居心叵测的人. 如果这个前提满足的话, 什么都好说, 就算是对称加密算法, 也不会有问题.
  2. 如果上面的大前提做不到, 那么至少应该做到, 私钥是被妥善保管的. 公钥分发给别人, 自己控制不了; 那么私钥的话自己是完全可以控制的, 应该妥善保管.
  3. 如果连上面的也做不到的话, 那下面的加密技术和措施就形同虚设了.

对称加密与非对称加密
对称加密是指双方使用同样的密钥, 密文是怎么生成的, 解密时还用怎样的逆过程来还原明文. 显然, 对称加密的算法是可逆的.这种算法的优点是非常简单容易实现. 这种算法的缺点是密钥管理的工作量很大. 比如你要和n个人加密通信, 你不能给他们用同样的一个密钥吧? 如果那样, 他们互相之间就能解密别人的通信, 并且人多事多, 密钥泄露给第三方的概率非常大. 所以, 你需要给他们每人一个密钥. 并且这些密钥你要保管好. 这在网络环境下是不现实的, 比如访问你的网站的人数以千万记, 你总不能每个人给一个密钥吧.

非对称加密是指有公钥和私钥的说法. 公钥私钥是一对. 两个东西都能够加密和解密, 但是它们都只能解密对方加密的东西. 也就是公钥加密的东西只能私钥解密, 私钥加密的东西只能公钥解密. 一般来讲, 自己保留的叫做私钥, 分发给别人的叫做公钥. 所以说, 私钥一般只有一份, 公钥却可以有很多份. 从这个角度较, 公钥被第三方不怀好意的人获取的可能性更大些. 
我们进行任何讨论的时候, 都是基于一个大前提: 私钥是被妥善保管的. 如果这个大前提不成立, 私钥被其他人获取了, 那么讨论啥都没价值了, 就好比你家的钥匙被别人复制了一份, 你家里财产的安全肯定没保证. 
仔细想想, 就算私钥妥善保管, 这个算法还是有问题的. 如果公钥被人获取, 那么这个人就可以阅读你发出的信息(虽然这个信息不是发给他的, 他截获之后就能用公钥解密阅读了). 如果所有人的公钥都是一样的, 那么只要获取公钥, 就能够阅读你发给所有人的信息了.
不过你确实能保证他无法阅读别人发给你的信息, 因为只有你手里的私钥才能解密公钥加密的信息.从这点来看, 非对称加密算法也只能确保单向通信的内容不被解密. 当然, 理想状况是你为所有的人都创建一个不同的公私钥对, 然后公钥私钥都是被妥善保存的. (如果真的是这么理想的话, 对称加密算法也是没有问题的, 我们发明更好的算法就是为了应对哪些并不是很理想的状况). 
在同等情况下, 非对称加密比对称加密强的地方是: 你最多只能破解我发出的东西, 你无法破解别人发给我的东西, 因为我会好好保护我的私钥不被你获取的.
后记: 单靠一个算法就想保证安全是不太可能的. 还需要更多的措施. 比如双方都有公钥私钥, 这一下子就是4个钥, 居心叵测的人想全都拿到手的话怕是比较困难.


数字签名
  1. 数据的发送方:首先取原始信息的hash值, 这个hash值叫做message digest. 这个过程是不可逆的, message digest无法还原成原始信息. 然后message digest又通过私钥加密, 生成的结果就叫作数字签名(digital signature). 数字签名会被附加到原始信息的后面.
  2. 数据的接收方: 收到信息之后, 首先用公钥解密signature, 把它转回成message digest. 如果这一步能够成功, 说明信息确实来自于那个发送者, 因为只有发送者才有那个跟公钥配对的私钥. 然后接受方也通过hash的方式提取信息的message digest, 然后比较自己得到的message digest和通过签名解密出来的message digest是否是一模一样的. 如果一模一样的话, 证明信息在传输的过程中没有被篡改过.
  3. 数字签名的作用, 我当前总结了两个: 首先能证明发送者的身份; 其次能证明信息在发送过程中没有被篡改过.
    1. 为何不把整个信息都加密? 而只是对信息的hash加密? 因为非对称加密的速度比较慢.
  4. 问题: 如果你可以用公钥解密signature, 只能证明这个signature是被跟你的公钥配对的那个私钥加密的, 不能证明私钥的持有者到底是谁. 比如我创建了公私钥对, 分发给一个人, 告诉他我是刘德华, 那么那个人没有很直接的手段来证明我是不是刘德华. 通过第三方权威机构的认证是可以的, 见下面的数字证书部分.

数字证书
  1. 上述的数字签名有个大漏洞, 比如我自己创建了公钥私钥对, 然后公钥发送给某某, 说自己是刘德华. 然后这个人相信了, 那么从此之后, 我就可以一直以刘德华的身份跟这个人通信了. 也许这不是一个纯粹技术性的问题, 但是我们确实需要一个方法来避免这种情况的发生.  这个方法就是数字证书(digital certificate)
  2. 数字证书是一种特殊的数字签名, 它由权威机构签发. 这个签名是用一个人的公钥和这个人的相关信息加密而成的. 接收方解密数字证书, 得出关于发送方的信息和公钥, 然后通过公钥解密信息, 如果信息能够被公钥解密, 说明这个信息确实是发送方创建的, 否则说明这个信息是第三方伪装成发送方发送的. 因为公钥是经过第三方权威认证的, 可以证明公钥属于那个发送者.
  3. 事实上有了第三方权威机构认证的机制, 很多接受者要求发送方一定要有权威机构的认证证书, 否则就不接受信息. 接收方也不需要有发送方的公钥, 因为第三方权威机构的签名可以被解密出发送方的公钥. 这样接收方只要有一个来自第三方权威机构的公钥就够了. 比如浏览器, 内置了很多权威机构的公钥, 用于解读它们签发出来的证书.
  4. 问题: 如果有人冒充权威机构呢? 或者这个所谓的权威机构靠不住呢? 比如前一段时间网民抵制CNNIC(中国的互联网信息中心)被添加到网络根证书认证机构的行列中. 如果这样的话, 政府可以伪造一个gmail的网站, 通过CNNIC认证这个网站, 客户的浏览器不会发出任何警告, 因为浏览器必须信任所有的网络根证书认证机构, 其中包括CNNIC.

TLS 与 SSL
TLS: Transport Layer Security; SSL: Security Security Layer. TLS是新出来的, 被认为是SSL的继任者. 比如gmail的smtp服务就用了TLS加密. 协议运行在Transport Layer只上. 协议有两个作用: 防止窃听和防止篡改.
一点点历史
  1. SSL 1.0被netscape开发, 但是没有公开发布
  2. 95年发布了SSL 2.0但是被认为有明显的缺陷, 于是很快被SSL 3.0(发布于96年)取代
  3. TLS1.0在99年推出, 作为SSL3.0的一个升级(所以TLS 1.0也叫做SSL 3.1). TLS 1.0 跟 SSL 3.0 之间的差别并不明显, 但是二者仍然是不能互通的. TLS 1.0提供了一个方式可以让通信降级为使用SSL 3.0
  4. TLS 1.1(也叫做SSL 3.2)06年推出; 
  5. TLS 1.2(也叫做SSL 3.3)08年推出. 11年3月TLS 1.2被修改, 不再兼容SSL 2.0版本(即通信永远不会降级到使用SSL 2.0).

TLS通信大致过程
  1. 客户端向支持TLS的服务器端发出信息, 给出自己支持的加密和Hash算法的列表
  2. 服务器端从中找出一个自己也支持的, 并且加密强度最好的, 回发给客户端
  3. 服务器端发给客户端一个数字证书, 这个证书中一般包含了server name, 自己信任的权威机构和自己的公钥.
  4. 客户端可以选择去权威机构确认下数字证书的合法性.(它也可以选择不去确认, 那就不是特别安全了)
  5. 客户端生成随机数, 用服务器的公钥加密, 然后发送给服务器. 只有服务器的私钥才可解读这个随机数
  6. 双方通过这个随机数生成加密解密的材料, 然后双方的通信就通过这些加密解密的材料进行, 直到连接的关闭. 也就说后续的通信采用的是对称加密.
  7. 如果上述步骤有一步失败了, 那么双方的连接就无法建立.

HTTPS
https就是http + ssl/tls. 也就是ssl/tls在http之上的一种使用方式而已, 没什么神秘的.