Dehydrated 使用 ZeroSSL 的方式

上一篇「ZeroSSL 也提供免費的 SSL Certificate (DV) 了」提到 ZeroSSL 的服務,而各家 acme client 也都陸陸續續支援了。

Dehydrated 是在 2020/09/15 的時候實做:「EAB + ZeroSSL support」,我就抓了個新版,更新之前自己包的 PPA dehydrated-lite...

Dehydrated 的設定方式還蠻簡單的,在 /etc/dehydrated/config 裡面這樣寫:

CA=zerossl
EAB_HMAC_KEY=x
EAB_KID=y

其中兩個 EAB 的資訊可以在 ZeroSSL 網站上面取得,然後其他就照舊跑...

ZeroSSL 也提供免費的 SSL Certificate (DV) 了

Facebook 上被朋友敲可以測 ZeroSSL,另外一個透過 ACME 協定提供免費的 SSL Certificate,不過目前只有支援單一網域名稱 (DV):「Another free CA as an alternative to Let's Encrypt (scotthelme.co.uk)」。

我先前就有在測 ZeroSSL,不過驗證一直過不去,當時有在 Twitter 上找 ZeroSSL 帳號問,但 ZeroSSL 的人說 ACME 的部份不在客服範圍,就先丟著...

剛剛發現是自己耍笨了,原因是 nginx 沒設好造成驗證卡住,一改好後就正常了。

SSL LabsSSL Server Test 翻了一下,他的 Root CA 看起來歷史更久,應該是有機會解決 Let's Encrypt 明年會產生的 Root CA 憑證信任問題,也就是先前在「Let's Encrypt 在 Android 平台上遇到的問題」提到的問題,在 Hacker News 上的討論也可以看到有人提到這點:

Good to know, and I'm glad there's an alternative to Let's Encrypt, just in case. Is ZeroSSL trusted by old Android devices? If so, that might be a work-around for Let's Encrypt's cross-signing from IdenTrust expiring.

不過也有些人有疑慮,畢竟提供這個服務後面的公司幹過不少壞事:

If zerossl is reselling/a subsidiary of sectigo, that’s enough reason to never use this.
Sectigo is the new name for Comodo. The same bunch of pricks who tried to trademark “Let’s Encrypt”.

Other players in the acme cert “business” is great. Renaming a slime ball name and carrying on like nothing happened is not ok.

但看起來至少是多了一個選擇...

Let's Encrypt 在 Android 平台上遇到的問題

同樣是「Standing on Our Own Two Feet」這篇文章,Let's Encrypt 預期明年九月後會在 Android 上遇到嚴重的相容性問題。

很舊的裝置主要是透過 IdenTrust 的 Root CA (DST Root CA X3) 對 Let's Encrypt 的 Intermediate CA (目前主要是 Let's Encrypt Authority X3) 簽名,從而建立憑證的信任鍊,而新的裝置除了 IdenTrust 的 CA 外,也信任了 Let's Encrypt 自家的 Root CA (ISRG Root X1):(出自「Chain of Trust」)

在 2016 年四月正式對外啟用時主要是靠 IdenTrust 的 cross-sign,而也是在 2016 年時 Let's Encrypt 自家的 Root CA (ISRG Root X1) 陸陸續續被各家收進 CA store。

所以這個時間點之前的 Android (大約是 7.1.1) 算是個相容性的分界線,在這個版本前 (而且系統無法更新的) 都只能靠 IdenTrust 的 cross-sign,這看起來大約有 33.8%,實際的流量大約是 1%~5%:

Currently, 66.2% of Android devices are running version 7.1 or above. The remaining 33.8% of Android devices will eventually start getting certificate errors when users visit sites that have a Let’s Encrypt certificate. In our communications with large integrators, we have found that this represents around 1-5% of traffic to their sites. Hopefully these numbers will be lower by the time DST Root X3 expires next year, but the change may not be very significant.

目前還有大約十個月左右的緩衝期,但大家都知道 Android 的更新速度,就十個月來說看起來不太樂觀...

官方有給他們不願意再取得一次 cross-sign 的原因,不過我覺得這個理由就很怪了,這個描述看起來是 IdenTrust 不願意再簽發一次?直覺覺得 IdenTrust 站在商業立場應該是很願意才對?而且除了 IdenTrust,應該也有其他家會有興趣?

Can we get another cross-signature? We’ve explored this option and it seems unlikely. It’s a big risk for a CA to cross-sign another CA’s certificate, since they become responsible for everything that CA does.

也有可能是放個話讓 IdenTrust 表態?先繼續看下去...

最差的情況應該就是沒有 cross-sign,然後也沒提供其他的 workaround,這樣就是買一般的 SSL certificate 來解了...

讓瀏覽器直接連 HTTPS 的 SVCB/HTTPS

Cloudflare 的「Speeding up HTTPS and HTTP/3 negotiation with... DNS」這篇裡面提到了一個新的標準 (目前是 draft):「Service binding and parameter specification via the DNS (DNS SVCB and HTTPS RRs)」。

從文件上可以看到這個標準是由 GoogleAkamai 的人提出來的,想要透過 DNS 的方式告訴瀏覽器這個網站可以直接用 HTTPS 連線 (以及其他資訊)。

這樣有兩個好處,第一個是安全性上的好處,HSTS 只保證了第二次以及之後的連線會強制用 HTTPS,但不能保證第一次連線時是 HTTPS。透過 DNS 查到後可以第一次就用 HTTPS 連線。

第二個是效能上的好處,降低了一個 3xx redirect 的時間,雖然 DNS 多了一些查詢,但 DNS 查詢這邊通常會比 TCP connection 建立連線來說快不少,再加上 HTTP protocol 需要先等瀏覽器端送出 HTTP header 後才有回應,這樣應該是快蠻多的。

文章裡有提到 iOS 14 好像有開始在嘗試,但我好像沒看到其他資料:

We began investigating and found these to be a part of Apple’s iOS14 beta release where they were testing out a new SVCB/HTTPS record type.

先繼續觀望看看標準怎麼發展...

Let's Encrypt 生了新的 Root 與 Intermediate Certificate

Let's Encrypt 弄了新的 Root Certificate 與 Intermediate Certificate:「Let's Encrypt's New Root and Intermediate Certificates」。

一方面是本來的 Intermediate Certificate 也快要要過期了,另外一方面是要利用 ECDSA 降低傳輸時的頻寬成本:

On Thursday, September 3rd, 2020, Let’s Encrypt issued six new certificates: one root, four intermediates, and one cross-sign. These new certificates are part of our larger plan to improve privacy on the web, by making ECDSA end-entity certificates widely available, and by making certificates smaller.

本來有 Let's Encrypt Authority {X1,X2,X3,X4} 四組 Intermediate Certificate,都是 RSA 2048 bits。

其中 X1 與 X2 差不多都到期了 (cross-signed 的已經過了,自家 ISRG Root X1 簽的剩不到一個月),不過這兩組已經沒在用了,這次就不管他了。

而 X3 與 X4 這兩組則是明年到期,會產生出新的 Intermediate Certificate,會叫做 R3 與 R4,跟之前一樣會被自家 ISRG Root X1 簽,以及 IdenTrust DST Root CA X3 簽:

For starters, we’ve issued two new 2048-bit RSA intermediates which we’re calling R3 and R4. These are both issued by ISRG Root X1, and have 5-year lifetimes. They will also be cross-signed by IdenTrust. They’re basically direct replacements for our current X3 and X4, which are expiring in a year. We expect to switch our primary issuance pipeline to use R3 later this year, which won’t have any real effect on issuance or renewal.

然後是本次的重頭戲,會弄出一個新的 Root Certificate,叫做 ISRG Root X2,以及兩個 Intermediate Certificate,叫做 E1 與 E2:

The other new certificates are more interesting. First up, we have the new ISRG Root X2, which has an ECDSA P-384 key instead of RSA, and is valid until 2040. Issued from that, we have two new intermediates, E1 and E2, which are both also ECDSA and are valid for 5 years.

主要的目的就是降低 TLS 連線時的 bandwidth,這次的設計預期可以降低將近 400 bytes:

While a 2048-bit RSA public key is about 256 bytes long, an ECDSA P-384 public key is only about 48 bytes. Similarly, the RSA signature will be another 256 bytes, while the ECDSA signature will only be 96 bytes. Factoring in some additional overhead, that’s a savings of nearly 400 bytes per certificate. Multiply that by how many certificates are in your chain, and how many connections you get in a day, and the bandwidth savings add up fast.

另外一個特別的修改是把名字改短 (把「Let's Encrypt Authority」拿掉),也是為了省傳輸的成本:

As an aside: since we’re concerned about certificate sizes, we’ve also taken a few other measures to save bytes in our new certificates. We’ve shortened their Subject Common Names from “Let’s Encrypt Authority X3” to just “R3”, relying on the previously-redundant Organization Name field to supply the words “Let’s Encrypt”. We’ve shortened their Authority Information Access Issuer and CRL Distribution Point URLs, and we’ve dropped their CPS and OCSP urls entirely. All of this adds up to another approximately 120 bytes of savings without making any substantive change to the useful information in the certificate.

這個部份讓我想到之前寫的「省頻寬的方法:終極版本...」這篇,裡面提到 AWS 自家的 SSL Certificate 太胖,改用 DigiCert 的反而可以省下不少錢 XDDD

另外也提到了這次 cross-sign 的部份是對 ECDSA Root Certificate 簽 (ISRG Root X2),而不是對 ECDSA Intermediate Certificate 簽 (E1 與 E2),主因是不希望多一次切換的轉移期:

In the end, we decided that providing the option of all-ECDSA chains was more important, and so opted to go with the first option, and cross-sign the ISRG Root X2 itself.

這算是蠻重要的進展,看起來各家 client 最近應該都會推出新版支援。

新的 TLS 攻擊:Raccoon Attack

這次看到的是針對 TLS 實做上的問題產生的 Raccoon Attack,反正先取個名字就對了,原圖有點大張,設個 medium size 好了 XDDD:

Why is the attack called "Raccoon"?
Raccoon is not an acronym. Raccoons are just cute animals, and it is well past time that an attack will be named after them :)

先講影響的產品,首先是經常中槍的 F5,這次連 timing measurement 都不需要太準確就可以打穿:

In particular, several F5 products allow executing a special version of the attack, without the need for precise timing measurements.

OpenSSL 的部份因為從 1.0.2f 之後因為其他的 security issue 所以改善了實做方式,就不會受到這次的攻擊手法影響。

剛剛翻了一下 Ubuntu 上的的資料,看起來 16.04 (xenial) 上的 OpenSSL 就已經是 1.0.2g 了,所以目前只要是有在 Ubuntu 支援的版本應該都不受影響:

OpenSSL assigned the issue CVE-2020-1968. OpenSSL does use fresh DH keys per default since version 1.0.2f (which made SSL_OP_SINGLE_DH_USE default as a response to CVE-2016-0701).

Firefox 直接拔了 DH 與 DHE 相關的 cipher suite,反正在這次攻擊手法出來前本來就已經計畫要拔掉:

Mozilla assigned the issue CVE-2020-12413. It has been solved by disabling DH and DHE cipher suites in Firefox (which was already planned before the Raccoon disclosure).

微軟的部份則是推更新出來:

Microsoft assigned the issue CVE-2020-1596. Please refer to the Microsoft Security Response Center portal.

回到攻擊手法,這次的問題是因為 DH 相關的實做造成的問題。

TLS 要求去掉 premaster secret 裡開頭的 0,造成會因為開頭的 0 數量不同而實做上就不會是 constant time,所以有了一些 side channel information 可以用:

Our Raccoon attack exploits a TLS specification side channel; TLS 1.2 (and all previous versions) prescribes that all leading zero bytes in the premaster secret are stripped before used in further computations. Since the resulting premaster secret is used as an input into the key derivation function, which is based on hash functions with different timing profiles, precise timing measurements may enable an attacker to construct an oracle from a TLS server.

然後一層一層堆,能夠知道 premaster secret 開頭是不是 0 之後,接下來因為 server side 會重複使用同一組 premaster secret,所以可以當作一個 oracle,試著去計算出更後面的位數:

This oracle tells the attacker whether a computed premaster secret starts with zero or not. For example, the attacker could eavesdrop ga sent by the client, resend it to the server, and determine whether the resulting premaster secret starts with zero or not.

Learning one byte from a premaster secret would not help the attacker much. However, here the attack gets interesting. Imagine the attacker intercepted a ClientKeyExchange message containing the value ga. The attacker can now construct values related to ga and send them to the server in distinct TLS handshakes. More concretely, the attacker constructs values gri*ga, which lead to premaster secrets gri*b*gab. Based on the server timing behavior, the attacker can find values leading to premaster secrets starting with zero. In the end, this helps the attacker to construct a set of equations and use a solver for the Hidden Number Problem (HNP) to compute the original premaster secret established between the client and the server.

所以針對這個攻擊手法的解法就是用「新鮮的」premaster secret (像是完全不重複使用),然後保留開頭的 0,不需要去掉。而 TLS 1.3 在定義的時候把這兩件事情都做了,所以不會受到影響:

Is TLS 1.3 also affected?
No. In TLS 1.3, the leading zero bytes are preserved for DHE cipher suites (as well as for ECDHE ones) and keys should not be reused.

另外在這邊提到的 Hidden Number Problem (HNP) 也是個不熟悉的詞彙,網站上有提到論文,也就是「Hardness of computing the most significant bits of secret keys in Diffie-Hellman and related schemes」這篇:

Given an oracle Oα(x) that on input x computes the k most significant bits of (α * gx mod p) , find α mod p.

是個離散對數類的問題,之後有空再來翻一翻好了。

CloudFront 支援 TLS 1.3

看到 AWS 的公告,宣佈 CloudFront 支援 TLS 1.3:「Amazon CloudFront announces support for TLSv1.3 for viewer connections」。

預設會自動啟用:

TLSv1.3 is available today and enabled by default across all Amazon CloudFront security policies options. No additional changes are required to your CloudFront configuration to benefit from the security and performance improvements of TLSv1.3 for your viewer connections.

對使用者最大的差異應該還是改善 first byte 的時間 (主要是因為 handshake 時間縮短),這點 AWS 的人也有提到在內部測試時,美國區的改善情況:

In our own internal tests in the US region as an example, first byte latency for new negotiated connections saw reductions of up to 33% for TLSv1.3 compared to previous versions of TLS.

在 latency 更高的地區應該也會有大幅改善...

中國開始擋 ESNI 了...

這兩天陸陸續續都有一些新聞出來了,中國已經開始擋 ESNI 了:「China is now blocking all encrypted HTTPS traffic that uses TLS 1.3 and ESNI」。

ESNI (Encrypted SNI) 的重點就是在於把 TLS 裡 ClientHello 的 hostname 部分加密 (通常會需要配合 DNS-over-HTTPS 或是 DNS-over-TLS 的方式取得 key 相關的資料),這個 hostname 的部分是目前 TLS 連線裡少數可以被看到的明文,也因此對於 GFW 過濾資料很有用,而 ESNI 等於是把這個洞補上,這次直接擋掉應該是預料中的事情...

但就算不管中國的部分,ESNI 對於 priavcy 的幫助還是很大,基本上 ISP 只剩下 IP 資訊可以分析,如果是有 CDN 之類的服務在前面擋住的就更看不出來了 (i.e. 許多網站用同一個 IP address)。

TLS 憑證的最長時效將從 825 天降到 398 天

在「Reducing TLS Certificate Lifespans to 398 Days」這邊看到才想起來沒寫這篇,這邊發生了一些有趣的事情...

提案是降低 TLS 憑證的有效時效,這件事情一開始是在 CA/B Forum 討論,但經過投票後沒有通過:「Ballot SC22 - Reduce Certificate Lifetimes (v2)」。

從投票記錄可以看到所有的憑證使用方 (包括了許多瀏覽器的廠商) 都贊同,但有大約 2/3 的憑證發行方都反對:

7 votes total including abstentions:

  • 7 Yes votes: Apple, Cisco, Google, Microsoft, Mozilla, Opera, 360
  • 0 No votes:
  • 0 Abstain:

33 votes total including abstentions

  • 11 Yes votes: Amazon, Buypass, Certigna (DHIMYOTIS), certSIGN, Sectigo (former Comodo CA), eMudhra, Kamu SM, Let’s Encrypt, Logius PKIoverheid, SHECA, SSL.com
  • 20 No votes: Camerfirma, Certum (Asseco), CFCA, Chunghwa Telecom, Comsign, D-TRUST, DarkMatter, Entrust Datacard, Firmaprofesional, GDCA, GlobalSign, GoDaddy, Izenpe, Network Solutions, OATI, SECOM, SwissSign, TWCA, TrustCor, SecureTrust (former Trustwave)
  • 2 Abstain: HARICA, TurkTrust

然後幾個比較大的憑證使用方 (AppleGoogleMozilla) 在提案被否決後就決定放到自家的規則了:「Apple strong-arms entire CA industry into one-year certificate lifespans」。

從 2020/09/01 開始,如果發出來的憑證超過 398 天就當作是無效憑證,也就是 2020/08/31 是最後一天可以發有效期限為 825 天的憑證,會落在 2022/12/05 失效:

$ date --date='Sep 1 2020 GMT+0000 +825days'
Mon Dec  5 08:00:00 CST 2022

這三家搞下去,就等於是強制性讓這些 CA 到九月就不能賣兩年的憑證了 (雖然還沒看到 Microsoft),這些 CA 一定是在心裡幹爆... XD

Let's Encrypt 在檢查 CAA 時出包

Let's Encrypt 發現在檢查 CAA 的程式碼有問題,發了說明:「2020.02.29 CAA Rechecking Bug」,以及預定的處理方式:「Revoking certain certificates on March 4」。

問題是當一個 certificate request 包含了 N 個 domain 時,本來的 CAA 檢查應該要對這 N 個檢查,但程式寫成只會抓一個,然後檢查了 N 次:

The bug: when a certificate request contained N domain names that needed CAA rechecking, Boulder would pick one domain name and check it N times. What this means in practice is that if a subscriber validated a domain name at time X, and the CAA records for that domain at time X allowed Let’s Encrypt issuance, that subscriber would be able to issue a certificate containing that domain name until X+30 days, even if someone later installed CAA records on that domain name that prohibit issuance by Let’s Encrypt.

2020/02/29 發現的,就程式碼的部屬時間,發現應該從去年 2019/07/25 開始就有這個 bug:

We confirmed the bug at 2020-02-29 03:08 UTC, and halted issuance at 03:10. We deployed a fix at 05:22 UTC and then re-enabled issuance.

Our preliminary investigation suggests the bug was introduced on 2019-07-25. We will conduct a more detailed investigation and provide a postmortem when it is complete.

然後決定要 revoke 這些可能會有問題的 SSL certificate,大約佔現有還有效的 SSL certificate 的 2.6%,大約三百萬筆:

Q: How many certificates are affected?
A: 2.6%. That is 3,048,289 currently-valid certificates are affected, out of ~116 million overall active Let’s Encrypt certificates. Of the affected certificates, about 1 million are duplicates of other affected certificates, in the sense of covering the same set of domain names.

在「Check whether a host's certificate needs replacement」這邊可以偵測線上使用的 SSL certificate 是否受到影響。

另外在「Download affected certificate serials for 2020.02.29 CAA Rechecking Incident」這邊可以抓到所有受到影響,預定要 revoke 的 SSL certificate 的序號。關於取得序號的方式,官方也有提供 CLI 的指令可以操作確認,對於有很多網域名稱需要確認的人可以用這組指令編寫程式判斷:

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | openssl x509 -text -noout | grep -A 1 Serial\ Number | tr -d :

照目前的描述,如果申請時只有一個 domain 應該是不會中這個問題,再來是最壞的情況大概會維持三個月 (網站主人沒管他,等到時間到了自動 renew)。