Lets Encrypt是如何颁发证书的

TL;NR

分成两个步骤。第一步验证agent对domain的所有权。
第二部才是给agent的domain颁发证书。

下面假设我们的服务器(上面跑着lets encrypt的agent)的域名是example.com.

验证agent拥有domain example.com

回忆一下我们在服务器上运行certbot certonly的时候,会弹出来几个选项,其中一个是spin up a temp server。

这个就是用来完成Lets encrypt的CA服务器对我们服务器拥有example.com的验证。

具体来说,agent会按照CA服务器的吩咐,放一个文件在example.com的目录下,然后CA服务器会亲自通过example.com来获取这个文件。能够获取则证明ok,我们的agent拥有example.com这个doamin。

接下来,因为要颁发证书,所以我们的agent需要提供一对公私钥。其中公钥我们称作A。CA服务器会产生一个随机数,然后我们的agent用私钥加密了之后,和公钥A一起丢给CA服务器,CA服务器验证ok,就用这个公钥A和你进行下面一个步骤。

看这个图,钥匙指的是我们约定好的公钥。为什么是A呢?因为表示是我们agent用到的。

颁发证书

验证搞定之后,agent会发起一个CRS。这个里面包含了我们实际要给服务器签名的公钥S。除了这个公钥,还包含了一个签名,这个签名是用公钥S对应的私钥对公钥S进行了签名的产物。

然后整个CRS再用之前约定好的公钥A的私钥进行签名,交给了CA服务器。

图中钥匙S就是代表实际上我们想要颁发证书的公钥。圆圈表示签名。然后CA先验证一下用公钥A的签名,再验证一下用公钥S的私钥对公钥S的签名,都没有问题的话,颁发证书,用公钥S对证书进行加密送回给agent。

理解上面三个图需要排除一个误区,就是上面除了最后加密颁发证书之外,都是明文+签名。使用明文中的公钥就能验证签名是否是又对应的私钥签发。

如果觉得抽象就想象一下jwt,jwt谁都可以看里面的内容,至于如何验证jwt有没有被篡改,就得看jwt后面带的一串签名,大概就是同样的意思。