Let's Encrypt 的 Embed SCT 支援

翻到 Let's EncryptUpcoming Features 時看到:

Embed SCT receipts in certificates
ETA: February, 2018

對 Embed SCT 不熟,所以查了查這個功能。

這指的是在簽發 SSL certficiate 後,把資料丟給 Certificate Transparency (CT) 伺服器後,伺服器會提供 signed certificate timestamp (SCT);而這個資料放到 SSL certificate 內叫做 Embed SCT:(出自 CT 的 FAQ)

What is an SCT?
An SCT is a signed certificate timestamp. When a certificate authority or a server operator submits a certificate to a log, the log responds with an SCT. An SCT is essentially a promise that the log server will add the certificate to the log in a specific time. The time, known as the maximum merge delay (MMD), helps ensure that certificates are added to logs in a reasonable time. The SCT accompanies the certificate until the certificate is revoked. A TLS server must present the SCT to a TLS client (along with the SSL certificate) during the TLS handshake.

當使用 ECC 時會小於 100 bytes:

How big is an SCT?
SCTs are less than 100 bytes, assuming elliptic curve signatures are used.

這樣才能試著解釋前幾天提到要拔掉 HPKP 的事情:「Chromium 內提案移除 HPKP (HTTP Public Key Pinning)」,也就是為什麼他們是提 CT 解,而不是 DNS CAA 解...

不過我記得 CT server 可以自己架自己 submit 不是嗎?後來有另外規定一定要用第三方的嗎?這樣又很怪...

Facebook 在 MySQL 裡存時間的型態

MySQL at Facebook這邊說明提到了,Facebook 內部是使用 INT UNSIGNED 儲存時間:

Which gets us to the point that it is no different than storing INT (hello 2038?) or UNSIGNED INT (a bit later) or BIGINT (till the end of time) and possibly passing binary values in efficient protocols eventually.

If you got that far of this post, your likes in Facebook graph are stored with 'INT UNSIGNED' time field.

順道一提,INT 是 2038 年問題,INT UNSIGNED 是 2106 年問題。

而 Facebook 在 MySQL 上會選擇不使用 DATETIMETIMESTAMP 的原因其實跟技術搭不上太多關係,主因是因為 MySQL 根本沒打算修 XDDD

It is my favorite MySQL bug, simply because it forces any reasonable mind not to use TIMESTAMP, and MySQL is never going to fix it (nor will ever understand time). I lost my temper a bit on that bug: https://bugs.mysql.com/bug.php?id=38455

我的猜測是已經爛成一團了,而且大家都有 workaround (呃,其實就是 Facebook 推薦用 INT UNSIGNED 的方法),再考慮到有一票現有程式,在上面狂用 side effect 讓執行結果正確,不如就不要修這種吃力不討好的東西了 XDDD

另外一方面 timezone 資訊其實常常變化,常常需要更新 MySQL 的 timezone database (而這對於維運來說不是什麼開心的事情):

There're few ways around that. One of them is side-load and maintain timezone data inside MySQL itself - it has support for internal timezone database and tracks obscure time shifts like ones for "Pacific War Time" and "Pacific Peace Time". That is operationally feasible (you have to remind yourself to update the database whenever time rules change, and they do change a lot, if you consider every timezone in the world), but has limited value.

這就是為什麼大家遇到 MySQL 時都會推薦用 INT UNSIGNED 了...

另外可以參考三年前的文章「MySQL 裡儲存時間的方式...」,裡面引用了 Baron Schwartz 的說明:

All date and time columns shall be INT UNSIGNED NOT NULL, and shall store a Unix timestamp in UTC.

其實這已經是個 best practice 了...

MySQL 裡儲存時間的方式...

這應該是 MySQL 的 best practice 之一,不知道為什麼 Baron Schwartz 又拿出來講:「A simple rule for sane timestamps in MySQL」。

MySQL 內可以儲存「日期與時間」的資料型態是 DATETIME 與 TIMESTAMP 兩種,不過 DATETIME 沒有時區觀念,而 TIMESTAMP 只能是 UTC (GMT+0)。

相較於隔壁棚 PostgreSQLDate/Time Types 就一種 TIMESTAMP,但支援 with timezone 與 without timezone 直接解決問題。

這使得 MySQL 上在儲存「日期與時間」以及處理的時候一直有種 WTF 的感覺...

就如同 Baron Schwartz 的建議,如果使用 MySQL,目前比較好的方法是用 INT UNSIGNED NOT NULL 儲存,把 timezone 的處理都放到應用程式端來處理,這樣產生的問題會比較少...

真的需要在 INSERT 或是 UPDATE 時更新欄位,可以用 trigger 處理,彈性反而比內建功能大不少。