#12 快速签发免费 SSL/TLS 证书
WebDev TLS TLSCert HTTPS 2026-05-18本文不涉及自动签发、自动更换证书,只对 acme.sh 工具的简单用法做一个记录。
coding in a complicated world
本文不涉及自动签发、自动更换证书,只对 acme.sh 工具的简单用法做一个记录。
Hello! In my networking zine (which everyone will be able to see soon), there is a page about TLS/SSL (basically this tweet). But as happens when you write 200 words about a thing on a page, there is a lot more interesting stuff to say. So in this post we will dissect an SSL certificates and try to understand it!
你好! 在我的网络杂志(每个人很快就能看到)中,有一个关于 TLS/SSL 的页面(基本上是这条推文)。 但当你在一页上写下 200 个关于某件事的字时,就会发现有很多更有趣的东西要说。 因此,在这篇文章中,我们将剖析 SSL 证书并尝试理解它!
I am not a security person and I am not going to give you security advice for your website (want to know what TLS ciphers you should use? I have no idea!!!). But! I think it’s interesting to know what it means to “issue a SSL certificate” and I can talk about that a little.
我不是安全人员,我不会为您的网站提供安全建议(想知道您应该使用什么 TLS 密码?我不知道!!!)。 但! 我认为了解“颁发 SSL 证书”的含义很有趣,我可以稍微讨论一下。
I was confused about what this “TLS” thing was for a long time. Basically newer versions of SSL are called TLS (the version after SSL 3.0 is TLS 1.0). I’m going to just call it “SSL” throughout because that is less confusing to me.
很长一段时间我都对“TLS”这个东西感到困惑。 基本上较新版本的 SSL 称为 TLS(SSL 3.0 之后的版本是 TLS 1.0)。 我将自始至终将其称为“SSL”,因为这对我来说不那么令人困惑。
Suppose I’m checking my email at https://mail.google.com
假设我正在 https://mail.google.com 检查我的电子邮件
mail.google.com is running a HTTPS server on port 443. I want to make sure that I’m actually talking to mail.google.com and not some other random server on the internet owned by EVIL PEOPLE.
“mail.google.com”正在端口 443 上运行 HTTPS 服务器。我想确保我实际上与 mail.google.com 进行通信,而不是与 EVIL PEOPLE 拥有的互联网上的其他随机服务器进行通信 。
This “certificate” business was kind of mysterious to me for a very long time. One day my cool coworker Ray told me that I could connect to a server on the command line and download its certificate!
很长一段时间以来,这个“证书”业务对我来说有点神秘。 有一天,我的酷同事 Ray 告诉我,我可以通过命令行连接到服务器并下载其证书!
(If you want to just look at an SSL certificate, you can click on the green lock in your browser and reliably get all the information you need. But this is more fun.)
(如果您只想查看 SSL 证书,您可以单击浏览器中的绿色锁,可靠地获取您需要的所有信息。但这更有趣。)
So, let’s start by looking at mail.google.com’s certificate and deconstruct it a bit.
那么,让我们首先查看 mail.google.com 的证书并对其进行一些解构。
First, we run openssl s_client -connect mail.google.com:443
首先,我们运行“openssl s_client -connect mail.google.com:443”
This is going to print a bunch of stuff, but we’ll just focus on the certificate. Here, it’s this thing:
这将打印一堆东西,但我们只关注证书。 在这里,就是这个东西:
$ openssl s_client -connect mail.google.com:443
...
-----BEGIN CERTIFICATE-----
MIIElDCCA3ygAwIBAgIIMmzfdZnO9pMwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTcwMTE4MTg1MjExWhcNMTcwNDEyMTg1MDAw
WjBpMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEYMBYGA1UEAwwPbWFp
bC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiYcr
C9Rn7g9xjsg7khqfRPxUnvpgGyCHqJMXxZGtdf+G02d07cPlMEeaGG12vHyVfRZD
tc/F1ZfwenH6gf0uMobtgw7n2NQa7T7qxuqSUDhZsO1sI1LL/Yqy8QHoooOZQWMz
ytuRA18zti4vQV1dCijADh0+NWI1GDUAKidbaH/fBRrStqBev5Bhq3ZaGj3fDjAO
7CG0Wk3n4Ov2yg44XOdgkLMzjdnbV8l6cZDC7lCK1VsEU1mEd0O0Dw4OcnHLuBPw
IkioZayhPOXDXUS+bhpmtEiCkt8kbHG6jNMC4m8t62Jaf/Si3XNcHhDa4wPCTvid
X//PuuNlRZVg3NjK/wIDAQABo4IBXjCCAVowHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMCwGA1UdEQQlMCOCD21haWwuZ29vZ2xlLmNvbYIQaW5ib3guZ29v
Z2xlLmNvbTBoBggrBgEFBQcBAQRcMFowKwYIKwYBBQUHMAKGH2h0dHA6Ly9wa2ku
Z29vZ2xlLmNvbS9HSUFHMi5jcnQwKwYIKwYBBQUHMAGGH2h0dHA6Ly9jbGllbnRz
MS5nb29nbGUuY29tL29jc3AwHQYDVR0OBBYEFI69aYCEtb2swbJJR3cMOTdcfvZ4
MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUSt0GFhu89mi1dvWBtrtiGrpagS8w
IQYDVR0gBBowGDAMBgorBgEEAdZ5AgUBMAgGBmeBDAECAjAwBgNVHR8EKTAnMCWg
I6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEB
CwUAA4IBAQAhiqQIwkGp1NmlLq89gjoAfpwaapHuRixxl2S54fyu/4WOHJJafqVA
Tya9J7GTUCyQ6nszCdVizVP26h9TKOs9LJw5jWV9SOnPU2UZKvrNnOUi2FUkCcuD
lsADdKSXNzye3jB88TENrWC/y3ysPdAgPO/sXzyRvNw8SVKl2+RqMDpSRpBptF9e
Lp+WLAM3xKS5SPwCNdCiA332o7qiKRKQm/6bbIWnm7hp/ZnLxbyKaIVytRdiwRNp
O/TTpRv2C708GA3PH6i1pYE86xm3w7lGhN9OiCZpKOJD6ZUH3W20idgPKYPBCO/N
Op2AF3I4iUGeQjXFVLgS6mjUvdLndL9G
-----END CERTIFICATE-----
So far, this is unintelligible nonsense. “MIIElDcca… WHAT?!”
It turns out that this nonsense is a format called “X509”, and the openssl command knows how to decode it.
So I saved this blob of text to a file called cert.pem. You can save it to your computer from this gist if you want to follow along.
Our next mission is to parse this certificate. We do that like this:
到目前为止,这都是难以理解的废话。 “MIIElDcca……什么?!”
原来这个废话是一种叫做“X509”的格式,而openssl命令知道如何解码它。
因此,我将这段文本保存到名为“cert.pem”的文件中。 如果您想继续操作,可以根据此要点将其保存到您的计算机上。
我们的下一个任务是解析此证书。 我们这样做:
$ openssl x509 -in cert.pem -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3633524695565792915 (0x326cdf7599cef693)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Google Inc, CN=Google Internet Authority G2
Validity
Not Before: Jan 18 18:52:11 2017 GMT
Not After : Apr 12 18:50:00 2017 GMT
Subject: C=US, ST=California, L=Mountain View, O=Google Inc, CN=mail.google.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:89:87:2b:0b:d4:67:ee:0f:71:8e:c8:3b:92:1a:
9f:44:fc:54:9e:fa:60:1b:20:87:a8:93:17:c5:91:
.... blah blah blah ............
c2:4e:f8:9d:5f:ff:cf:ba:e3:65:45:95:60:dc:d8:
ca:ff
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:mail.google.com, DNS:inbox.google.com
X509v3 Subject Key Identifier:
8E:BD:69:80:84:B5:BD:AC:C1:B2:49:47:77:0C:39:37:5C:7E:F6:78
Signature Algorithm: sha256WithRSAEncryption
21:8a:a4:08:c2:41:a9:d4:d9:a5:2e:af:3d:82:3a:00:7e:9c:
1a:6a:91:ee:46:2c:71:97:64:b9:e1:fc:ae:ff:85:8e:1c:92:
......... blah blah blah more goes here ...........
This is a lot of stuff. Here are the parts of this that I understand
CN=mail.google.com is the “common name”. Counterintuitively you should ignore this field and look at the “subject alternative name” field insteadX509v3 Subject Alternative Name: section has the list of domains that this certificate works for. This is mail.google.com and inbox.google.com, which makes sense – they’re both email domains.Public Key Info section tells us the public key that we’re going to use to communicate with mail.google.com. We do not have time to explain public key cryptography right now, but this is basically the encryption key we’re going to use to talk secretly.So let’s talk about certificate signing.
这是很多东西。 这是我理解的部分
CN=mail.google.com 是“通用名称”。 与直觉相反,您应该忽略此字段并查看“主题备用名称”字段那么我们来谈谈证书签名。
Every certificate on the internet is basically two parts put together
I have a bunch of certificates on my computer in /etc/ssl/certs. Those are the certificates my computer trusts to sign other certificates. For example, I have /etc/ssl/certs/Staat_der_Nederlanden_EV_Root_CA.pem on my laptop. Some certificate from the Netherlands! Who knows! If they signed a mail.google.com certificate, my computer would be like “yep, looks great, sounds awesome”.
If some random person across the street signed a certificate, my computer would be like “I have no idea who you are”, and reject the certificate.
The mail.google certificate is
I have an /etc/ssl/certs/GeoTrust_Global_CA.pem file on my computer, which I think is why I trust this mail.google.com certificate. (Geotrust signed Google’s certificate, and Google signed mail.google.com)
互联网上的每个证书基本上都是由两部分组合而成
我的计算机上的 /etc/ssl/certs 中有一堆证书。 这些是我的计算机信任的用于签署其他证书的证书。 例如,我的笔记本电脑上有“/etc/ssl/certs/Staat_der_Nederlanden_EV_Root_CA.pem”。 荷兰的一些证书! 谁知道! 如果他们签署了“mail.google.com”证书,我的计算机就会说“是的,看起来很棒,听起来很棒”。
如果街对面的某个随机人签署了证书,我的计算机就会像“我不知道你是谁”一样,并拒绝该证书。
mail.google 证书是
我的计算机上有一个 /etc/ssl/certs/GeoTrust_Global_CA.pem 文件,我认为这就是我信任此 mail.google.com 证书的原因。 (Geotrust 签署了 Google 的证书,Google 签署了 mail.google.com)
So when you get a certificate issued, basically how it works is:
This “certificate authorities are supposed to have integrity thing” I think is why people get so mad when there are issues like this with Symantec where they generated test certificates “to unregistered domains and domains for which Symantec did not have authorization from the domain owner”
因此,当您获得颁发的证书时,其工作原理基本上是:
我认为“证书颁发机构应该保持诚信”,这就是为什么人们在出现[赛门铁克的此类问题](https://www.symantec.com/page.jsp?id=test-certs- 更新),他们为“未注册的域以及赛门铁克未获得域所有者授权的域”生成了测试证书
The last thing we are going to talk about is certificate transparency. This is a super interesting thing and has a good website and I am almost certainly going to mangle it.
I will try anyway!
So, we said that certificate authorities are “supposed to have integrity”. But there are SO MANY certificate authorities that my computer trusts! And at any time one of them could sign a rogue certificate for mail.google.com. That’s no good.
This isn’t a hypothetical issue – the certificate transparency website talks about more than one instance where a CA has been compromised or otherwise has made a mistake.
So, here’s the deal. At any given time, Google knows all the valid certificates that are supposed to exist for mail.google.com (there is probably only one or something). So certificate transparency is basically a way to make sure that if there is a certificate in circulation for mail.google.com that they DON’T know about, that they can find out.
Here are the steps, as I understand them
So if that CA in the Netherlands signs an evil mail.google.com certificate, they either have to put it in the public log (and Google will find out about their evil ways) or leave it out of the public log (and browsers will reject it).
我们要讨论的最后一件事是证书透明度。 这是一件非常有趣的事情,并且有一个很好的网站,我几乎肯定会破坏它。
无论如何我都会尝试!
因此,我们说证书颁发机构“应该具有完整性”。 但是我的计算机信任很多证书颁发机构! 他们中的任何一个人都可以随时为 mail.google.com 签署一份流氓证书。 那可不行。
这不是一个假设的问题 - 证书透明度 网站讨论了不止一个 CA 已被泄露或以其他方式做出了 错误。
所以,这就是交易。 在任何给定时间,Google 知道“mail.google.com”应存在的所有有效证书(可能只有一个或某项)。 因此,证书透明度基本上是一种确保 mail.google.com 是否有他们不知道的证书在流通的方法,他们可以找到。
据我了解,这是步骤
因此,如果荷兰的 CA 签署了邪恶的 mail.google.com 证书,他们要么必须将其放入公共日志中(Google 会发现他们的邪恶方式),要么将其从公共日志中删除(浏览器将 拒绝它)。
Okay! We have downloaded a SSL certificate and dissected it and learned a few things about it. Hopefully some of you have learned something!
Picking the right settings for your SSL certificates and SSL configuration on your webserver is confusing. As far as I understand it there are about 3 billion settings. Here is an example of an SSL Labs result for mail.google.com. There is all this stuff like OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 on that page (for real, that is a real thing.). I’m happy there are tools like SSL Labs that help mortals make sense of all of it.
Someone told me https://cipherli.st/ is a way to pick secure SSL configuration if you’re not sure what to do. I don’t know if it’s good or not.
好的! 我们已经下载了 SSL 证书并对其进行了剖析并了解了一些有关它的信息。 希望你们中的一些人学到了一些东西!
为 Web 服务器上的 SSL 证书和 SSL 配置选择正确的设置是令人困惑的。 据我了解,大约有 30 亿个设置。 以下是 mail.google.com 的 SSL 实验室结果示例。 该页面上有诸如“OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256”之类的所有内容(实际上,这是真实的东西。)。 我很高兴有像 SSL Labs 这样的工具可以帮助普通人理解这一切。
有人告诉我,如果您不确定该怎么做,https://cipherli.st/ 是选择安全 SSL 配置的一种方法。 我不知道这好不好。
Also let’s encrypt is really cool! They let you have a certificate for your site and make it secure, and you don’t even need to understand all this stuff about how certificates work on the inside! And it’s FREE.
另外,let’s encrypt 真的很酷! 它们让您拥有网站的证书并确保其安全,您甚至不需要了解所有有关证书内部工作原理的内容! 而且它是免费的。
echo | openssl s_client -connect sendcloud.net:443
echo | openssl s_client -showcerts -connect sendcloud.net:443
echo | openssl s_client -showcerts -debug -connect sendcloud.net:443 >/dev/null
echo | openssl s_client -showcerts -debug -connect sendcloud.net:443 2>/dev/null | openssl x509 -inform pem -noout -text
# 导出证书
openssl s_client -connect sendcloud.net:443 </dev/null | openssl x509 -outform pem > sendcloud.net.cer
# 导出所有证书
openssl s_client -showcerts -connect sendcloud.net:443 </dev/null | sed -n '/-----BEGIN/,/-----END/p' > sendcloud.net.cer
# 查看证书信息
openssl s_client -showcerts -connect sendcloud.net:443 </dev/null | sed -n '/-----BEGIN/,/-----END/p' | openssl x509 -noout -text
# 查看证书链上所有证书信息
OLDIFS=$IFS; IFS=':' certs=$(openssl s_client -showcerts -connect sendcloud.net:443 2>/dev/null </dev/null | sed -n '/-----BEGIN/,/-----END/{/-----BEGIN/ s/^/:/; p}'); for cert in ${certs#:}; do echo $cert | openssl x509 -noout -text; done; IFS=$OLDIFS
# # 查看证书链上所有证书 OCSP URI
OLDIFS=$IFS; IFS=':' certs=$(openssl s_client -showcerts -connect sendcloud.net:443 2>/dev/null </dev/null | sed -n '/-----BEGIN/,/-----END/{/-----BEGIN/ s/^/:/; p}'); for cert in ${certs#:}; do echo $cert | openssl x509 -noout -ocsp_uri; done; IFS=$OLDIFS
# -ocsp_uri
# -serial
# -fingerprint
# -subject
# 检查证书在 30 天之后有没有过期
openssl s_client -connect sendcloud.net:443 2>/dev/null </dev/null | openssl x509 -outform pem | openssl x509 -noout -checkend 2592000
# -checkend intmax Check whether the cert expires in the next arg seconds
# -checkhost val Check certificate matches host
# -checkemail val Check certificate matches email
# -checkip val Check certificate matches ipaddr
echo | openssl s_client -verify_hostname baidu.com -connect sendcloud.net:443 1>/dev/null
一样的,只是加 -starttls smtp。
echo | openssl s_client -connect smtp.sendcloud.net:25 -starttls smtp
echo | openssl s_client -connect smtp.sendcloud.net:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -text
校验证书
# echo | openssl s_client -connect smtp.sendcloud.net:25 -starttls smtp 2>/dev/null | openssl verify
# echo | openssl s_client -showcerts -connect smtp.sendcloud.net:25 -starttls smtp 2>/dev/null | openssl verify
echo | openssl s_client -showcerts -connect smtp.sendcloud.net:25 -starttls smtp 2>/dev/null | sed -n '/-----BEGIN/,/-----END/p' > smtp.sendcloud.net.cer
openssl verify -CAfile smtp.sendcloud.net.cer smtp.sendcloud.net.cer
IMAP
echo | openssl s_client -connect imap.126.com:143 -starttls imap
测试 TLS 1.3 支持
echo | openssl s_client -connect smtp.sendcloud.net:25 -starttls smtp -tls1_3
OCSP 检测
用上面的 sendcloud.net.cer 举例,需要将文件中第一个证书和下面的其他证书拆开,分成 sendcloud.cer 和 chain.cer
openssl x509 -noout -ocsp_uri -in sendcloud.cer
# http://ocsp.sectigo.com
openssl ocsp -issuer chain.cer -cert sendcloud.cer -text -url http://ocsp.sectigo.com
# Error querying OCSP responder
# 140052849842064:error:27076072:OCSP routines:PARSE_HTTP_LINE1:server response error:ocsp_ht.c:314:Code=400,Reason=Bad Request
遇到上面报错是因为 OSCP 客户端使用 HTTP 1.0,但是服务器端现在都是 1.1,需要 Host 头。
$ openssl ocsp -issuer chain.cer -cert sendcloud.cer -text -url http://ocsp.sectigo.com -header "HOST" "ocsp.sectigo.com"
OCSP Request Data:
Version: 1 (0x0)
Requestor List:
Certificate ID:
Hash Algorithm: sha1
Issuer Name Hash: 21F3459A10CAA6C84BDA1E3962B127D5338A7C48
Issuer Key Hash: 17D9D6252767F931C24943D93036448C6CA94FEB
Serial Number: DB5F1FFAFFB770CA38E8120A6121852E
Request Extensions:
OCSP Nonce:
0410F47624DDB17E9703BFCDCC96E983018B
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
Version: 1 (0x0)
Responder Id: 17D9D6252767F931C24943D93036448C6CA94FEB
Produced At: Dec 9 07:52:17 2023 GMT
Responses:
Certificate ID:
Hash Algorithm: sha1
Issuer Name Hash: 21F3459A10CAA6C84BDA1E3962B127D5338A7C48
Issuer Key Hash: 17D9D6252767F931C24943D93036448C6CA94FEB
Serial Number: DB5F1FFAFFB770CA38E8120A6121852E
Cert Status: good
This Update: Dec 9 07:52:17 2023 GMT
Next Update: Dec 16 07:52:16 2023 GMT
Signature Algorithm: sha256WithRSAEncryption
5f:65:bf:3e:d1:8c:16:63:76:bc:83:82:b8:a3:67:54:1d:26:
78:e1:b9:7f:64:c7:61:bc:40:0d:4b:b0:7f:49:29:bc:38:48:
43:87:a5:dd:a1:e6:b4:74:ce:58:44:24:30:c3:0d:f5:ab:da:
8c:f9:25:0e:3e:e2:fe:5a:64:5f:32:d9:f5:15:6f:0c:0c:89:
97:30:f6:6c:07:56:6e:54:81:4f:d3:22:1f:16:94:a0:2b:99:
49:2f:2c:0f:c8:b7:b4:90:2f:60:01:54:9c:f9:34:c0:c6:e1:
09:3f:93:d4:dd:a7:0b:34:bb:cb:4b:06:c3:5a:8c:fc:dc:85:
4f:9d:a7:08:c3:22:98:06:b8:b9:d4:47:51:9c:36:43:f3:53:
db:f5:d1:2f:4c:a6:97:c7:5a:f5:15:04:c4:94:a4:9e:95:4c:
03:fd:5a:60:b8:4c:75:e8:02:74:e4:80:1c:8f:17:85:8a:a2:
9e:b9:5d:74:4a:2e:7d:9f:5e:d8:40:6b:60:63:74:3f:dc:11:
d4:f6:b4:86:6e:6b:83:8a:ff:57:cf:b4:41:1f:a3:66:b2:e2:
00:6a:3a:33:dc:c3:3d:13:1d:37:97:d9:9c:d9:b5:9b:24:74:
24:82:7a:f9:ca:51:b3:39:24:e3:90:f4:ff:4b:8e:be:f8:0f:
ec:7a:16:55
WARNING: no nonce in response
Response Verify Failure
139766041024400:error:27069076:OCSP routines:OCSP_basic_verify:signer certificate not found:ocsp_vfy.c:92:
sendcloud.cer: good
This Update: Dec 9 07:52:17 2023 GMT
Next Update: Dec 16 07:52:16 2023 GMT
HTTPS = HTTP + TLS
原来是 TCP -> HTTP
现在是 TCP -> TLS -> HTTP
提升了安全性的同时,降低了一些性能。
更重要的是,互联网基础设施层面开始淘汰 HTTP:
相关通信过程在 2021/01/08,了解 HTTPS 背后的原理 有描述。
损耗主要在哪些环节呢?
参考 HTTPS 的资源消耗,针对消耗点进行优化。
在 2012 年的 RFC 6797 中,HTTP 严格传输安全被定义为网络安全标准。 创建这个标准的主要目的,是为了。
HSTS(HTTP 严格传输安全)
RFC 6797。
作用是避免用户遭受使用 SSL stripping(剥离,HTTP 降级攻击) 的 中间人攻击(man-in-The-middle,MITM)
add_header Strict-Transport-Security "max-age=31536000";
HTTP/2 支持
HSTS 全称 HTTP Strict Transport Security,中文就是 HTTP 严格传输安全。
HSTS 的作用是通过特定的 HTTP 响应头告知浏览器,未来访问该网站时必须使用 HTTPS 连接,确保通信的安全性。这可以避免用户通过 HTTP 访问时的自动重定向,从而减少延迟。
对于同时支持 HTTP 和 HTTPS 的站点,HSTS 强制客户端始终使用 HTTPS,防止潜在的中间人攻击。主流浏览器都已全面支持 HSTS。
HSTS 于 2012 年成为互联网标准建议(RFC 6797),并逐渐被广泛采用。
SSL 剥离攻击(SSLStrip),HTTP 降级攻击
受益于一整套相对可靠的公钥基础设施(PKI),直接的 HTTPS 通信是无法中间人攻击的。
中间人的伪造证书会被校验出来。
但是部分网站都是配置 HTTP 和 HTTPS 地址共存。
通过 Strict-Transport-Security 响应头(下面称之为 HSTS 头),告诉客户端应该采用 HTTPS 连接。
客户端以后再访问这个网站就会自动重定向到 HTTPS(即使指定了 HTTP 协议)。
Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains; preload
max-age 作用时长(秒),表示在这么长的时间之内都应该直接请求 HTTPS 协议。includeSubDomains 对所有子域名生效preload 添加到 HSTS 预加载列表需要的例如:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
表示两年之内,当前域名以及所有子域名,都通过 HTTPS 访问。
作用:强行指定相关域名采用 HTTPS 访问协议
要求原文:
80 rewrite 到 https
server {
listen 80;
server_name example.com;
# rewrite ^(.*)$ https://$host$1 permanent;
return 301 https://$server_name$request_uri;
}
HSTS 头
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
和 HSTS 类似,服务器告诉浏览器网站的证书指纹,浏览器缓存起来。
后面的每次访问都会计算证书指纹,如果和之前缓存的哈希不匹配,则向用户发出警告,存在中间人攻击风险。
计算证书指纹的方法:
和 HSTS 类似的是工作方式,目的(提升安全性),不同的是手段,HSTS 是为了确保采用安全的协议,PKP 是确保证书不被伪造。
上一篇:2021-08-08, OCSP 联机证书状态协议
rm -rf /tmp/ocsptest/; mkdir -p /tmp/ocsptest/; cd /tmp/ocsptest/; ls
# 获取证书
openssl s_client -showcerts -connect markjour.com:443 < /dev/null | awk -v c=-1 '/-----BEGIN CERTIFICATE-----/{f=1;c++}f {print > ("l"c".crt")}/---END CERTIFICATE-----/{f=0}'
cat l*.crt > chain.crt
# 获取 OCSP URL
ocspUrl=$(openssl x509 -noout -text -in l0.crt | grep OCSP | xargs); ocspUrl=${ocspUrl#*URI:}; echo $ocspUrl;
# http://ocsp.digicert.com
# 获取证书序列号
serial=$(openssl x509 -serial -noout -in l0.crt); serial=${serial#*=}; echo $serial;
# 01F284D36E08179CF4CEB5D339FE95E9
# OCSP 校验
openssl ocsp -nonce -issuer l1.crt -CAfile chain.crt -url $ocspUrl -serial "0x${serial}"
# WARNING: no nonce in response
# Response verify OK
# 0x01F284D36E08179CF4CEB5D339FE95E9: good
# This Update: Jan 21 08:15:01 2022 GMT
# Next Update: Jan 28 07:30:01 2022 GMT
证书使用者拿到证书之后会对其进行完整性校验,可信性校验,有效期校验,适用范围校验。可是其中少了一环:如果证书使用者出于什么原因主动注销证书,如何通知已经在使用该证书的人呢?
PKI (公开密钥基础建设) 有 CRL ((Certificate Revocation List 证书撤销列表) 和 OCSP (Online Certificate Status Protocol 联机证书状态协议) 两套机制。

TLS, Transport Layer Security, 传输层安全性协议
SSL, Secure Sockets Layer, 安全套接层
| 协议 | 发布时间 | 状态 | 说明 |
|---|---|---|---|
| SSL 1.0 | 未公布 | 未公布 | |
| SSL 2.0 | 1995 年 | 2011 年弃用 | |
| SSL 3.0 | 1996 年 | 2015 年弃用 | |
| TLS 1.0 | 1999 年 | 2021 年弃用 | RFC 2246 |
| TLS 1.1 | 2006 年 | 2021 年弃用 | RFC 4346 |
| TLS 1.2 | 2008 年 | RFC 5246 | |
| TLS 1.3 | 2018 年 | RFC 8446 |
现在主流的是 TLS 1.2 和 TLS 1.3。
相比之下,TLS 1.3 安全性更好,性能也更好。
搜索一下 tls1.2 tls1.3 difference 或者 tls1.2 tls1.3 performance 就能看到很多相关比较。
SSL/TLS 的本质就是非对称加密。
安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。
该协议由两层组成:
- TLS 记录协议(TLS Record)
- TLS 握手协议(TLS Handshake)
握手协议(handshake protocol)
密钥规格变更协议(change cipher spec protocol)
应用数据协议(application data protocol)
警报协议(alert protocol)。
HTTP/2 规范并没有要求使用 TLS,但是主流浏览器开发商全部选择在 TLS 之上实现 HTTP/2。
微软宣布从 2022 年 9 月 13 日起, Internet Explorer 和 EdgeHTML( WebView 控件的呈现引擎) 将默认禁用 TLS 1.0 和 1.1。禁用 TLS 1.0 和 1.1 的工作早在 2020 年提出,但当时新冠病毒在全球爆发,大量开发者居家办公,微软只能推迟淘汰 TLS 1.0 和 1.1 的时间。
注意:不是弃用,仍然可以通过配置打开相关支持。