[译]关于证书,我所知道的一切——证书颁发机构
原文:All I Know About Certificates -- Certificate Authority
TLS 握手中的关键步骤之一是服务器向客户端证明其身份。虽然有很多关于握手原则的内容,但有关证书(TLS/SSL 的重要组成部分)的信息却较少。本文将解释证书用于何处、谷歌如何防止他人冒充谷歌以及为何经常出现证书问题等内容。
(附言:写这篇文章花了我整整十个小时。非常简单,没有数学内容,只是几个 OpenSSL 命令。读起来很长,所以请随意拿杯啤酒慢慢看吧。)
证书能解决什么问题?
想象一下,有一个名为 super-bank.com
的银行,它持有数十亿美元的客户资金,并允许用户通过其网站进行转账。
现在,一个黑客走进星巴克,连接到 WiFi,并使用伪造的 DHCP 服务告诉其他用户:“我是网关,请让我转发您的互联网流量!” 这样他就可以看到所有用户的用户名和密码。
一些读者可能会说,“你可以使用 TLS 加密!”
然而,黑客通过某种方式获得了 super-bank.com
的证书,然后建立了一个假服务器,并告诉用户,“相信我,我是银行!”
于是,他再次窃取了用户的密码...
那么问题出在哪里呢?问题在于证书。 证书的作用是:只有持有证书的人才是真正的 super-bank.com
。
换句话说,它证明了“我是我所声称的人”。
一个常见的误解是,只有证书颁发机构才能签发证书。事实上,任何人都可以发行证书。我可以自己创建根证书,并为任何域签发证书。可能有很多证书,但客户端必须信任有效的那些。
那么,哪些证书是值得信赖的呢? 由权威证书颁发机构(CA)签发的证书。
这个话题之所以复杂,是因为这三个参与者——客户端、CA 和网站——彼此相连,但每个都有自己的责任。在讨论中,很容易混淆他们的角色,导致误解。因此,这一系列文章将分别讨论这些参与者的议题和行动,希望澄清问题。
它们的关系是:
- 客户端信任 CA。
- CA 向网站颁发证书。
- 当客户端访问网站时,该网站会展示其证书。由于客户端信任 CA,所以它也信任由 CA 签发的证书。
这就像在餐厅吃饭:你怎么知道它不是骗局?你会检查这家餐厅是否有监管机构颁发的营业执照。如果餐厅有执照,那么你就会相信这个餐厅。
现在,这个问题似乎很简单,但如果我们考虑打破信任链的方法,我们会发现解决这个“信任”问题并不简单。
例如,我可以向 CA 申请为 super-bank.com
颁发证书吗? 为什么 CA 不给我发这个证书呢?
证书颁发机构
证书颁发机构(CA)有三个主要职责:
- 对网站:当有人申请证书时,我必须验证申请人的真实身份。如果他们不是超级银行,我就不能给他们发证书。
- 对自己:保护根证书的私钥。
- 对客户:获得客户的信任。
验证网站身份
我们不能把证书发给错误的人,因为这会让持有者冒充他人。因此,对于所有申请人,我们必须确保在颁发证书之前他们确实控制着域名。这意味着要验证申请人的身份。
这个行业的标准被称为 ACME 挑战。 基本原则是: 证明给我(CA)看,你是 superbank.com
, 你需要让URL superbank.com/.well-known/acme-challenge/foo
返回文本bar
。 这就证明了你对域名的所有权,然后我就可以给你颁发证书了。(也有其他支持的方法,比如 DNS TXT 记录)。
保护私钥
证书颁发机构 (CA) 必须保护其私钥,因为如果泄露,他们就无法再担任该角色。拥有泄露密钥的人可以随意发布证书。如果私钥被泄露,这对 CA 来说将是灾难性的。颁发机构发放的所有证书都将需要撤销,网站都需要重新部署新的证书,而且如果客户端不及时撤销受攻击的 CA,则可能面临访问欺诈服务器的风险,从而导致潜在的账户盗窃和欺诈行为。
鉴于需要证书(包括在到期时重新发行)的网站数量众多,如果 CA 在每次颁发证书时都要从安全存储库中访问私钥,则效率会非常低。
中级证书的使用
为了解决这个问题,CA 根证书通常不会直接签发给网站。相反,它会签发一个中间证书,然后用该中间证书来签发给网站。
这就引出了 x509:如果客户端信任根证书颁发机构,那么它应该信任由该机构签发的 证书,并且还应该信任这些证书所引用的证书,依此类推。但这是否意味着由根证书颁发机构签发给我的证书可以被我用来签发其他证书?那就意味着任何人都可以用根证书颁发机构的信誉来签发证书。
证书签名
当然不是。 由 CA 颁发的证书包括一个 X509v3 基本约束:关键字段,其值为CA:FALSE
。通过下载此博客的证书并使用 OpenSSL 工具解析它,您会发现该证书链中的根证书和中间证书都有 CA:TRUE,而我的证书有 CA:FALSE。
证书颁发给实体时,CA:FALSE 值意味着即使它们签发了证书,也不会被信任。我们能否修改此字段以签发证书?
答案是肯定的,但如果我修改了自己的证书,那么这个被修改过的证书就不再可信了。
信任链
客户信任->根 CA 信任->中级 CA 不信任->kawabangga.com 不信任 -> 由 kawabangga.com 签名的 super-bank.com
为什么修改后的证书不被信任?
证书签发流程
证书签发过程很简单,利用了公钥和私钥的特点:
- 用私钥签名的数据可以用公钥验证。
- 用公钥加密的数据可以使用私钥解密。
简而言之,这意味着用一个密钥加密的数据只能用另一个密钥解密。 其中一把钥匙作为公钥发布出去,另一把则被保密保存。
签名的过程本质上涉及加密:
- 对整个证书进行哈希,然后用私钥加密哈希值。
- 验证者对整个证书进行哈希并获取哈希值,然后使用公钥解密加密的哈希值。 如果两者匹配,则可以确认私钥持有人进行了加密。
客户验证流程
客户端通过比较使用公钥解密的哈希值与计算的哈希值来验证证书。
这保证了:
- 签名者不能否认他们的行为,因为只有私钥持有者才能签名。
- 签名的内容无法被篡改;任何修改都会导致验证失败。
因此,在 CA 签署证书后,证书中的任何部分都不能被修改,包括 CA:FALSE 和有效期。如果过期了,必须重新签署证书。简单地更改日期以延长其使用时间是行不通的。
许多人错误地认为证书签发涉及 CA 使用其证书进行签名。 事实上,CA 仅使用其私钥将加密散列值附加到原始证书。
证书颁发机构必须受客户端信任
一切的基础都是客户必须信任 CA。对所有其他证书的信任都源于对根证书的信任。
建立信任是一个漫长的过程。
那么客户端如何信任证书颁发机构呢?答案是客户端会本地存储 CA。具体的位置取决于客户端:例如,在 Linux 上,它在 /etc/ssl/certs
中;在 Mac 上,可以使用钥匙串查看。Chrome 的受信任证书在这里,Mozilla 的在这里。
考虑到世界上有大量的客户,添加新的 CA 似乎很困难!
事实上,它并没有。2013 年,一群雄心勃勃的人创立了一个名为 Let's Encrypt 的组织:“我们希望为所有需要 TLS / SSL 证书的网站提供免费证书!以友好的方式!因为我们想要一个更安全、更私密的互联网。”
新的证书颁发机构从何而来?事实上,这个 CA 不需要花费很多年的时间来慢慢赢得所有用户 的信任。如前所述,它只需要一个根证书颁发机构的信任就可以了。如果一个客户端信任一个旧的 CA,并且旧的 CA 签名了新的 CA,那么该客户端就会信任新的 CA。在这种情况下,旧的 CA 就是 DST 根 CA X3。根据这一逻辑,客户端信任 DST 根 CA X3,因此信任由 DST 根 CA X3 签名的 Let's Encrypt 证书,以及由 Let's Encrypt 签名的中间证书,但不会进一步向下。记住 CA:FALSE 吗?
有了这么多证书,客户端如何验证它们呢?听起来很麻烦,也不清楚该相信谁。
接下来我们来探索客户的作用: