https = http + tls tcp 三次握手建立连接后,再进行 tls 握手/协商得到一个秘钥,然后双方使用这个秘钥加密(对称加密)明文的 http 为密文后再发送,同样双方收到密文后也用这个秘钥解密得到明文

对称加密使用同一秘钥加密和解密,性能高,http 明文就是通过对称加密后才进行传输的,对称加密算法有:DES3DESAES 等;但秘钥交换是个问题,所以需要非对称加密的帮助

非对称加密公钥加密则私钥解密,私钥加密则公钥解密,性能比对称加密要差,不适合加解密大量的数据,但很适合于解决秘钥交换的问题,常用的有:RSADSA

tls 协商/握手

Client Hello 客户端发送:客户端随机数(client random)和客户端支持的 加密套件列表
Server Hello 服务端从客户端支持的加密套件中选择一个,然后发送:服务端随机数(server random)和 选用的套件,比如 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 就是:
• 密钥协商使用 ECDHE
• 签名算法使用 RSA
• 加密 http 明文所使用的对称加密算法是 AES,密钥长度 256,分组模式 GCM
• 摘要算法使用 SHA384
Server Certificate 服务端发送 CA 证书
Server Key Exchange 服务端生成一个随机数作为 服务端椭圆曲线私钥,选择一个 椭圆曲线(比如 named_curve)和 椭圆曲线基点 G,根据 G 和服务端椭圆曲线私钥生成 服务端椭圆曲线公钥
为了确保服务端椭圆曲线公钥不被篡改,服务端用 RSA + 服务端 CA 私钥给服务端椭圆曲线公钥做个签名 signature
最后发送椭圆曲线、G、服务端椭圆曲线公钥和 signature 给客户端
Server Hello Done 服务端告诉客户端我这边的信息已经发送完毕
Client Key Exchange 客户端进行 CA 证书校验;同样生成一个随机数作为 客户端椭圆曲线私钥,根据服务端给的 G 和客户端椭圆曲线私钥生成 客户端椭圆曲线公钥 发给服务端(服务端 CA 公钥加密签名防篡改)
此时客户端算出椭圆曲线秘钥 = f(客户端椭圆曲线私钥,服务端椭圆曲线公钥),服务端也算出椭圆曲线秘钥 = f(服务端椭圆曲线私钥,客户端椭圆曲线公钥)
而两端算出的 椭圆曲线秘钥 是一致的,但这还没有结束,对 http 明文进行加密的 主秘钥 = server random + client random + 椭圆曲线秘钥
Change Cipher Spec 服务端和客户端都通知对方,后续的数据传输将使用 RSA + 主秘钥加密了
Finish 第一个由 tls 记录层协议进行加密保护的信息,双方需要验证对方发送的 Finished 信息,保证协商的密钥是可用的,保证协商过程中,没有被篡改

dh.png

总结

https 使用对称加密(比如 RSA)对 http 明文进行加密传输,这个秘钥叫主秘钥,但要确保秘钥交换过程是安全的;那怎样的交换过程是安全的呢?当然不交换,服务端和客户端各自按照一定的规则生成相同秘钥最安全!这个规则就是 密钥协商协议

DH(Diffie-Hellman)算法是 Whitfield Diffie 和 Martin Hellman 在 1976 年公布的一种密钥交换算法,它是一种建立密钥的方法而不是加密方法,所以密钥必须和其他一种加密算法结合使用。这种密钥交换技术的目的在于使两个用户安全的协商一个会话密码。Diffie-Hellman 密钥交换算法的有效性依赖于计算离散对数的难度。

总的来说 DH 靠本地计算替代网络传输保证了秘钥的安全

cert_chain.png

SSL 证书包括 CA 证书 和 用户证书 两种

CA 全称 Certification Authority(证书颁发机构),顾名思义是专门给别人颁发证书的机构,它的证书叫做 CA 证书,大部分 CA 证书会被内置到 Android、iOS、Chrome、Firefox 等软件里面并受到信任

CA 颁发的证书包括 根证书 和 中间证书 两种:

用户证书是由 CA 中间证书签发给用户的证书,包含服务器证书和客户端证书

证书文件格式

// 谷歌邮箱的证书
$ openssl x509 -in ./mail.google.com -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            5c:48:a5:bd:db:83:49:69:12:a9:54:9f:08:5d:b1:d5
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
        Validity
            Not Before: Nov  2 13:45:40 2022 GMT
            Not After : Jan 25 13:45:39 2023 GMT
        Subject: CN = mail.google.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:48:6e:8d:70:27:fd:14:77:98:20:c4:71:c2:18:
                    83:fe:f7:fe:3d:20:2e:b7:5b:87:31:5d:69:ca:2f:
                    07:3a:cb:cc:5a:2a:9b:18:26:43:a1:76:5f:92:42:
                    5e:4e:bf:2e:8c:89:3e:6e:cf:6e:21:74:38:94:d0:
                    5e:08:bc:ad:0f
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                E1:AF:FF:77:26:9C:2D:37:42:00:C5:30:3A:81:A2:01:90:A8:2C:1F
            X509v3 Authority Key Identifier:
                keyid:8A:74:7F:AF:85:CD:EE:95:CD:3D:9C:D0:E2:46:14:F3:71:35:1D:27

            Authority Information Access:
                OCSP - URI:<http://ocsp.pki.goog/gts1c3>
                CA Issuers - URI:<http://pki.goog/repo/certs/gts1c3.der>

            X509v3 Subject Alternative Name:
                DNS:mail.google.com, DNS:inbox.google.com
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.11129.2.5.3

            X509v3 CRL Distribution Points:

                Full Name:
                  URI:<http://crls.pki.goog/gts1c3/QOvJ0N1sT2A.crl>

            CT Precertificate SCTs:
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : E8:3E:D0:DA:3E:F5:06:35:32:E7:57:28:BC:89:6B:C9:
                                03:D3:CB:D1:11:6B:EC:EB:69:E1:77:7D:6D:06:BD:6E
                    Timestamp : Nov  2 14:45:42.034 2022 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:45:02:20:55:B9:3F:3A:67:2C:6D:51:09:80:E1:BB:
                                8D:5B:EF:19:7C:37:B8:4A:A9:D3:A8:D0:0C:07:A5:AE:
                                F7:15:F3:D2:02:21:00:FB:4E:96:FE:38:FE:27:AF:7E:
                                63:41:F6:30:9B:66:4E:43:D0:D6:6B:4F:C1:43:68:14:
                                5D:B6:58:B8:37:28:B4
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : B3:73:77:07:E1:84:50:F8:63:86:D6:05:A9:DC:11:09:
                                4A:79:2D:B1:67:0C:0B:87:DC:F0:03:0E:79:36:A5:9A
                    Timestamp : Nov  2 14:45:42.195 2022 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:46:02:21:00:ED:AB:D5:12:61:88:24:CF:40:C6:45:
                                9B:C0:29:4D:50:CE:E3:54:4D:05:63:06:CE:46:38:A9:
                                03:17:5C:11:44:02:21:00:9E:57:54:CE:BC:25:CA:8B:
                                6C:26:98:52:DF:03:0C:CE:43:46:E9:AA:9B:83:20:F2:
                                1B:94:FD:52:EB:E1:C1:4B
    Signature Algorithm: sha256WithRSAEncryption
         9d:04:e6:b9:2c:a9:77:0a:11:54:28:3e:6f:83:50:a5:87:14:
         03:ba:cc:85:0f:cb:c8:1f:a9:e8:d0:44:b7:a9:c8:86:98:6c:
         9a:8e:89:2f:cd:bb:36:82:52:29:2e:28:a8:d3:76:31:5a:71:
         e5:91:6d:4c:b6:ad:79:d7:a8:c8:a6:ed:ec:09:4b:e0:a4:e4:
         07:b5:5e:d0:c4:a8:50:92:01:df:53:4d:fd:e5:d0:ac:5f:43:
         b5:64:d2:a8:f9:1c:2c:aa:f1:0a:d3:69:d4:6d:03:60:63:b0:
         f2:0b:5a:74:35:73:72:b6:86:2c:93:08:e9:92:69:68:78:90:
         16:b7:fe:b7:ab:72:46:f8:30:21:8b:6d:86:a1:99:6a:fa:be:
         0e:c6:f4:d3:c7:d6:80:4f:b1:36:d3:b5:34:cd:f6:12:d6:55:
         c5:a7:7d:bb:84:81:f0:34:87:17:11:a9:42:a9:d0:8b:cf:05:
         28:3b:fb:89:f9:0f:af:c4:32:3f:31:60:19:70:b9:10:6e:6a:
         64:40:28:5f:ba:d5:6e:8d:8c:40:b7:a0:d7:2c:68:41:50:af:
         f7:bf:e9:f1:a0:03:98:c1:66:ee:31:97:54:66:e8:ed:4f:67:
         c0:70:f7:12:32:9f:c3:50:b6:4a:7e:0b:f9:73:86:de:34:df:
         94:e5:bb:9b

// Charles 代理软件的自签名证书
$ openssl x509 -in ./charles.pem -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1648018041505 (0x17fb587aaa1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = "Charles Proxy CA (23 Mar 2022, \\\\E4\\\\BA\\\\92\\\\E8\\\\81\\\\94\\\\E7\\\\BD\\\\91\\\\E5\\\\BC\\\\80\\\\E5\\\\8F\\\\91\\\\E9\\\\83\\\\A8-\\\\E6\\\\9E\\\\97\\\\E5\\\\A8\\\\81)", OU = <https://charlesproxy.com/ssl>, O = XK72 Ltd, L = Auckland, ST = Auckland, C = NZ
        Validity
            Not Before: Mar 22 06:47:21 2022 GMT
            Not After : Mar 22 06:47:21 2023 GMT
        Subject: CN = "Charles Proxy CA (23 Mar 2022, \\\\E4\\\\BA\\\\92\\\\E8\\\\81\\\\94\\\\E7\\\\BD\\\\91\\\\E5\\\\BC\\\\80\\\\E5\\\\8F\\\\91\\\\E9\\\\83\\\\A8-\\\\E6\\\\9E\\\\97\\\\E5\\\\A8\\\\81)", OU = <https://charlesproxy.com/ssl>, O = XK72 Ltd, L = Auckland, ST = Auckland, C = NZ
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b8:ca:61:56:ee:b3:ae:94:0d:2b:5d:da:c0:a1:
                    cb:e3:3e:d2:19:22:03:88:57:0d:a6:96:7e:4f:2e:
                    11:9e:8d:45:c6:ef:e8:d7:86:dc:eb:a6:94:56:d9:
                    25:0e:63:4a:1d:37:22:1d:e5:83:19:c7:1b:a3:c8:
                    d7:69:29:82:dc:e7:a7:04:66:73:f1:1e:1c:16:6f:
                    fd:e5:79:97:c5:b5:29:d3:a9:27:3a:f3:88:c0:6a:
                    ef:e9:e4:5f:c4:5d:68:80:f2:bf:65:75:25:24:c3:
                    e6:44:74:1c:e8:5d:c3:06:45:13:cc:7c:fd:b2:70:
                    ed:d1:41:9c:ae:33:b7:5e:84:c6:4b:67:86:41:d1:
                    75:2b:79:6c:52:e5:8b:58:05:68:3b:42:1b:a0:35:
                    85:bf:3f:25:05:b4:a5:60:68:d0:6d:42:63:37:e1:
                    67:82:e3:3d:2e:d6:9f:9a:8a:ff:2f:14:df:df:cc:
                    cf:67:a9:4f:68:19:18:a2:f6:6d:95:46:79:e7:4d:
                    93:58:25:f5:fb:21:f0:40:59:38:0b:4c:a3:c8:7f:
                    9d:2f:12:87:fc:0a:20:08:75:e8:29:a7:d0:44:48:
                    d1:d8:36:f5:6a:53:eb:e0:6f:5a:41:ce:f8:1b:f2:
                    e3:35:d3:c1:03:86:30:17:0c:0b:d5:f4:59:90:81:
                    6c:79
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            Netscape Comment:
                ....This Root certificate was generated by Charles Proxy for SSL Proxying. If this certificate is part of a certificate chain, this means that you're browsing through Charles Proxy with SSL Proxying enabled for this website. Please see <http://charlesproxy.com/ssl> for more information.
            X509v3 Key Usage: critical
                Certificate Sign
            X509v3 Subject Key Identifier:
                4D:45:D9:BF:C6:09:B5:13:ED:13:C0:39:AF:21:8A:FF:48:F2:F8:D0
    Signature Algorithm: sha256WithRSAEncryption
         8c:7b:ed:c6:f9:1b:ed:ba:e9:ed:6c:07:a8:0d:ff:7b:05:30:
         1c:cd:cf:78:17:21:14:74:f7:f3:91:ba:12:2d:ef:98:91:94:
         a3:d8:13:62:0f:05:31:57:86:54:48:02:7f:96:91:5a:d5:95:
         10:78:ab:ba:f5:9f:18:1f:d1:23:b2:74:01:87:d7:d2:9b:ec:
         94:b6:c7:4b:d6:28:d0:b7:07:17:65:e2:8a:5e:36:cd:93:5a:
         cd:e9:bc:8e:00:ca:5d:f6:14:2a:ac:b8:de:38:91:3c:8d:14:
         27:32:0b:5b:72:de:ee:7c:a6:81:bf:d8:b5:ba:67:e2:f6:9e:
         35:5d:ef:c8:77:f1:ef:8d:b2:54:b7:70:12:29:39:3d:b8:12:
         a0:22:4a:b1:d5:62:ba:35:a2:9d:4d:54:5d:c5:e7:ab:0a:54:
         28:f9:b0:8d:8f:ec:48:ef:27:38:a6:6e:ba:62:28:ba:ca:60:
         92:09:f2:cd:2b:23:85:1c:c5:93:2d:96:e6:30:69:f8:d0:cf:
         6d:3f:e3:6e:52:c2:b1:af:be:75:d3:ba:35:58:b6:de:21:a3:
         33:ea:fc:11:ed:08:87:a2:95:e8:3b:06:d4:c0:5f:a5:7e:a4:
         39:52:d1:40:18:6a:38:22:07:fc:c9:78:8f:a7:dc:9b:7b:13:
         71:a9:6c:53

证书的数据结构

Issuer 是颁发机构也即 CA,Subject 是主体也即 CA 认证的对象,一般是域名:mail.google.com、*.cnblogs.com,它们有几个描述字段:

Validity 是证书有效期:[Not Before, Not After]

证书中还包含主体的公钥信息 Subject Public Key Info,包括公钥算法和公钥,这样服务器下发证书给客户端时,客户端也就拿到了服务端的公钥

还有非常重要的、确保证书未被篡改的签名信息 Signature Algorithm,包括签名算法和签名,这是由颁发机构用它的私钥签发的,客户端可以通过 CA 证书里的公钥校验

证书校验流程

  1. 证书的下发与校验发生在 SSL 握手期间,服务端在第三步下发证书给客户端,客户端在第六步进行证书的校验
  2. 校验证书链

CA 会给颁发的证书签名,所谓签名就是用 CA 私钥对证书摘要进行加密操作得到输出:encrypt(digest(cert), privKey) = signature,那么校验签名就是:digest(cert) == decrypt(signature, pubKey)

客户端可以通过服务端证书的 Issuer 字段得知 CA,然后在内置/配置的受信任 CA 列表里找到对应的 CA 证书,从 CA 证书的 Subject Public Key Info 找到 CA 公钥 pubKey

用服务端证书签名字段 Signature Algorithm 里的加密算法 decrypt,和上面找到的 CA 公钥 pubKey,解密签名得到正确的证书摘要 signed digest = decrypt(signature, pubKey),这个摘要是受到 CA 私钥加密保护的所以无法被篡改

客户端计算服务端证书的摘要 digest = digest(cert),如果与 signed digest 一致说明证书未篡改

重复以上过程直到最终构建出一条完整的证书链,这个证书链的顶端必须是受信任的根 CA,这条证书链才算校验通过

  1. 是否在上级证书的吊销列表里

有两种方式:

  1. 证书是否过期

Validity 字段,证书有效期在 [Not Before, Not After] 之间

  1. 服务器域名是否与证书主体匹配

比如访问谷歌邮箱 https://mail.google.com/mail/u/0/#inbox,服务端下发的证书里的主体是 Subject: CN = mail.google.com

主体名还可以用通配符,比如博客园 https://www.cnblogs.com/blogs-of-lxl/p/10136582.html 里证书主体是 Subject: CN = *.cnblogs.com

自定义 CA

然而现实情况往往来得更加复杂: