PuTTY 使用 ecdsa-sha2-nistp521 的漏洞

看到「PuTTY vulnerability vuln-p521-bias (greenend.org.uk)」這個消息,官網的說明在「PuTTY vulnerability vuln-p521-bias」這邊。

DSA 類的簽名演算法有個得很小心的地方,是 nonce 選擇不當會造成 key recovery,這在原文有提到:

All DSA signature schemes require a random value to be invented during signing, known as the 'nonce' (cryptography jargon for a value used only once), or sometimes by the letter k. It's well known that if an attacker can guess the value of k you used, or find any two signatures you generated with the same k, then they can immediately recover your private key.

維基百科的業面上也有提到這點:

With DSA, the entropy, secrecy, and uniqueness of the random signature value {\displaystyle k} are critical. It is so critical that violating any one of those three requirements can reveal the entire private key to an attacker. Using the same value twice (even while keeping {\displaystyle k} secret), using a predictable value, or leaking even a few bits of {\displaystyle k} in each of several signatures, is enough to reveal the private key {\displaystyle x}.

這次爆炸的起因是 PuTTY 用了 SHA-512 產生 nonce,這邊只會有 512 bits 的輸出,而這對 P-521 需要 521 bits 是不夠的 (於是前 9 個 bit 會是 0):

PuTTY's technique worked by making a SHA-512 hash, and then reducing it mod q, where q is the order of the group used in the DSA system. For integer DSA (for which PuTTY's technique was originally developed), q is about 160 bits; for elliptic-curve DSA (which came later) it has about the same number of bits as the curve modulus, so 256 or 384 or 521 bits for the NIST curves.

In all of those cases except P521, the bias introduced by reducing a 512-bit number mod q is negligible. But in the case of P521, where q has 521 bits (i.e. more than 512), reducing a 512-bit number mod q has no effect at all – you get a value of k whose top 9 bits are always zero.

而更糟的是,這不僅僅是將降了 29 的安全性,而是因為 nonce 有 bias,這在 DSA 上已經足以從 60 次的簽出的 signature 中還原出 private key (也就是文章裡提到的 key recovery attack):

This bias is sufficient to allow a key recovery attack. It's less immediate than if an attacker knows all of k, but it turns out that if k has a biased distribution in this way, it's possible to aggregate information from multiple signatures and recover the private key eventually. Apparently the number of signatures required is around 60.

新版會改用 RFC 6979 (Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)) 實作:

To fix this vulnerability, we've completely abandoned PuTTY's old system for generating k, and switched to the RFC 6979 technique, for all DSA and ECDSA key types. (EdDSA keys such as Ed25519 already used a different system, which has not changed.) However, this doesn't affect the fact that information about existing P521 private keys has already been leaked whenever a signature was generated using the old k generator.

所以這次的 fix 得更新 PuTTY 版本,然後重新產生 private key (會假設已經 leak 了),然後看看系統有什麼要處理的...

UUID 的 UX

在「The UX of UUIDs (unkey.dev)」這邊看到的紋章,原文在「The UX of UUIDs」。

裡面有不少是有幫助的建議,像是第一個建議是把 UUID 裡面的 - 拿掉,這樣對於 copy 比較方便 (畢竟大多數人應該是 copy UUID,不會是念出來?)。

第二個建議是加上 prefix,這點不一定侷限在 UUID,只要是 token 上面都很適合。這個在不少系統上應該都有看過,像是 GitHub 的 token,或是 AWS 的 token 都算是這類。

文章裡面沒有提到,但這個建議也可以幫助你在 CI 上設定 regex,擋下把 secret token 寫進去的行為。

第三個提到用 base58,一方面是減少長度,另外一方面是想要避免 1IiLl0Oo 的問題,這點我覺得還好... 既然都是 copy & paste 了,我覺得拿 base62 (i.e. 大小寫加上數字) 不錯,這避免特殊字元無法選擇到,也就是文章裡面第一個建議。

第四個建議是建議重新思考 range,因為 UUID 的 128-bit range 很大,但不是所有應用都需要用到這麼大的範圍確保 collision-free (於是可以當 primary key)。

這點讓我想到 X (Twitter) 當初發表的 Snowflake ID,在 Twitter 這種規模下 64-bit range 也已經夠用。

後面的文章內容就是在推銷自家東西,我就... 跳過了。

Let's Encrypt 簽發新的 Intermediate CA

Let's Encrypt 宣佈簽發新的 Intermediate CA:「New Intermediate Certificates」。

這次用 ISRG Root X1 簽了很多東西出來:

On Wednesday, March 13, 2024, Let’s Encrypt generated 10 new Intermediate CA Key Pairs, and issued 15 new Intermediate CA Certificates containing the new public keys.

ISRG Root X1 簽了五組 2048-bit RSA 的 intermediate CA,被叫做 R10~R14:

We created 5 new 2048-bit RSA intermediate certificates named in sequence from R10 through R14. These are issued by ISRG Root X1. You can think of them as direct replacements for our existing R3 and R4 intermediates.

另外 ISRG Root X1 也簽出五組 P-384 ECDSA 的 intermediate CA,被叫做 E5~E9;另外 ISRG Root X2 也簽了 E5~E9:

We also created 5 new P-384 ECDSA intermediate certificates named in sequence from E5 through E9. Each of these is represented by two certificates: one issued by ISRG Root X2 (exactly like our existing E1 and E2), and one issued (or cross-signed) by ISRG Root X1.

所以總共是產生了 10 組 intermediate certificate,然後簽了 15 組 intermediate CA 出來。

另外這邊有個比較特別的是 ISRG Root X1 (RSA 4096) 也簽了 ISRG Root X2 (ECDSA P-384),理論上 ISRG Root X2 這組後續應該也會開始放到各家的 root store 裡面...

用官方的圖可以說明這些關係:

目前還沒上線,先簽出來並且公告,後續才會切換過去。

另外在紋章裡面提到了 app 應該避免對 intermediate certificate 鎖定 (key pinning):

We are very hopeful that these steps will prevent intermediate key pinning altogether, and help the WebPKI remain agile moving forward.

Intermediate CA 在安全理由上是需要定時更換的,真的要做的話,應該是對 Root CA 做比較好。

CloudFront 支援 4096-bit RSA 的 SSL/TLS certificate 了

CloudFront 總算支援 4096-bit 的 RSA SSL/TLS certificate 了:「Amazon CloudFront now supports 4096-bit RSA TLS certificates」。

翻了一下 AWS ACM,看起來是 2020 年以前就支援 4096-bit RSA SSL/TLS certificate 了,CloudFront 晚蠻多的...

另外查了一下目前的強度,NSA 給出 2048-bit RSA 對到 112-bit strength,而 3072-bit RSA 對到 128-bit strength;至於 4096-bit RSA,目前是估算大約在 140-bit strength,有點微妙的數字。

看起來主要應該是給 compliance 需求使用的,有些舊的 library 未必支援 ECC 類的演算法,還是得透過拉高 RSA key size 來增加安全性。

Amazon RDS 的 TLS 連線所使用的 CA 要更新了

Amazon RDSTLS (SSL) 連線所使用的 CA 要更新了:「Rotate Your SSL/TLS Certificates Now – Amazon RDS and Amazon Aurora Expire in 2024」。

如果沒有開 TLS 連線的話是不受影響 (像是內網裸奔),但如果有在用 TLS 的話就要注意一下了,看起來得手動更新處理。

比較特別的是新的 CA 簽的超長:

Most SSL/TLS certificates (rds-ca-2019) for your DB instances will expire in 2024 after the certificate update in 2020. In December 2022, we released new CA certificates that are valid for 40 years (rds-ca-rsa2048-g1) and 100 years (rds-ca-rsa4096-g1 and rds-ca-ecc384-g1). So, if you rotate your CA certificates, you don’t need to do It again for a long time.

現有的 rds-ca-2019 可以在 https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem 這邊取得,用 openssl x509 -in rds-ca-2019-root.pem -text 可以看到資料。

crt.sh 上翻過一些字串,沒看到被簽的記錄,所以看起來無法透過一般 trusted store 裡面的 Root CA 一路信任下來。

新的 key 應該也是 Private Root CA,從名字看起來應該是對應的 key algorithm。其中 RSA 2048 的簽了 40 年,而 RSA 4096 與 ECC 384 的簽了 100 年,雖然說是自家弄的 CA,但目前的 compliance 沒有要求 key rotation 嗎...

Anyway,常用的區域基本上都是 August 22, 2024 這個日期,大約還有九個多月的時間更新,依照 AWS 的慣例,後面應該還會提醒幾次:

話說 2020 年的時候也有更新,當時是 Jeff Barr 出來說明的:「Urgent & Important – Rotate Your Amazon RDS, Aurora, and Amazon DocumentDB (with MongoDB compatibility) Certificates」,現在看起來一些常態性的說明都陸續交棒給 Channy Yun 了...

不過這次這樣搞 40 年 & 100 年,後續要更新應該都是演算法的推進了,比較不會是要到期...

自己小修一下 fcitx5-mcbopomofo 的選詞數量

之前有提過「Linux 上 fcitx5 的小麥輸入法」,在我自己桌面都換成 Ubuntu 22.04 後都能裝了,就用了一陣子。

但選字的數量一直覺得怪怪的,本來的數量是九個,像是這樣:

看了一下 Windows 上的新酷音,介面上因為設計成 3x3 的關係,所以看起來就不會不舒服:

所以就在想,如果是一行的為什麼不是十個?翻了翻程式碼,看起來在 src/McBopomofo.cpp 這邊:

  if (keysConfig == SelectionKeys::Key_asdfghjkl) {
    selectionKeys_.emplace_back(FcitxKey_a);
    selectionKeys_.emplace_back(FcitxKey_s);
    selectionKeys_.emplace_back(FcitxKey_d);
    selectionKeys_.emplace_back(FcitxKey_f);
    selectionKeys_.emplace_back(FcitxKey_g);
    selectionKeys_.emplace_back(FcitxKey_h);
    selectionKeys_.emplace_back(FcitxKey_j);
    selectionKeys_.emplace_back(FcitxKey_k);
    selectionKeys_.emplace_back(FcitxKey_l);
  } else if (keysConfig == SelectionKeys::Key_asdfzxcvb) {
    selectionKeys_.emplace_back(FcitxKey_a);
    selectionKeys_.emplace_back(FcitxKey_s);
    selectionKeys_.emplace_back(FcitxKey_d);
    selectionKeys_.emplace_back(FcitxKey_f);
    selectionKeys_.emplace_back(FcitxKey_z);
    selectionKeys_.emplace_back(FcitxKey_x);
    selectionKeys_.emplace_back(FcitxKey_c);
    selectionKeys_.emplace_back(FcitxKey_v);
    selectionKeys_.emplace_back(FcitxKey_b);
  } else {
    selectionKeys_.emplace_back(FcitxKey_1);
    selectionKeys_.emplace_back(FcitxKey_2);
    selectionKeys_.emplace_back(FcitxKey_3);
    selectionKeys_.emplace_back(FcitxKey_4);
    selectionKeys_.emplace_back(FcitxKey_5);
    selectionKeys_.emplace_back(FcitxKey_6);
    selectionKeys_.emplace_back(FcitxKey_7);
    selectionKeys_.emplace_back(FcitxKey_8);
    selectionKeys_.emplace_back(FcitxKey_9);
  }

看起來是為了跟 asdfghjkl 九個鍵對齊設計的,但這樣覺得不舒服... 所以在 selectionKeys_.emplace_back(FcitxKey_9); 後面加上 selectionKeys_.emplace_back(FcitxKey_0);,再重新編 + 裝 + 重啟後再輸入就變成十個了:

這樣自己用是沒問題,但暫時想不到怎麼找出一個好方法併回去... 也許多一組 SelectionKeys::Key_1234567890

OpenSSH 與 Dropbear 對 Ed25519 的支援

查了一下這兩個 server 端的軟體支援 Ed25519 的時間點。

OpenSSH 是在 2014/01/30 的 6.5 就支援了:

* ssh(1), sshd(8): Add support for Ed25519 as a public key type. Ed25519 is a elliptic curve signature scheme that offers better security than ECDSA and DSA and good performance. It may be used for both user and host keys.

算是相當久以前就支援了。對應到第一個支援的 Debian 版本是 Jessie 使用的 OpenSSH 6.7:「sshd(8) — openssh-server — Debian jessie — Debian Manpages」;第一個支援的 Ubuntu (LTS) 版本是 Trusty (14.04) 用的 OpenSSH 6.6:「openssh source package in Trusty」。

Dropbear 這邊就晚不少,在 2020/06/15 的 2020.79 版本才支援:

- Support ed25519 hostkeys and authorized_keys, many thanks to Vladislav Grishenko. This also replaces curve25519 with a TweetNaCl implementation that reduces code size.

所以對應到第一個支援的 Debian 版本是 Bullseye 的 2020.81:「Debian -- Details of package dropbear in bullseye」;第一個支援 Ubuntu (LTS) 的版本是 Jammy (22.04) 的 2020.81:「Ubuntu – Details of package dropbear in jammy」。

這樣看起來如果就是想要用 Ed25519 的話,變成 server 端的軟體得配合:預設裝的 sshd 應該都是 OpenSSH,如果想要換 Dropbear 的話要看 distribution 內給的版本夠不夠新,或是透過 PPA 之類的方法裝新版。

但大多數採用 BusyBox 的機器應該沒有採用新版 Dropbear (像是 AP 刷機),這邊還是得使用其他 key format,如果要避開 NIST 有介入的格式,就還是得用 ssh-rsa 了。

GitHub 更換 github.com 的 SSH host key (RSA 部份)

看到 GitHub 宣佈更換 SSH key (RSA 的部份):「We updated our RSA SSH host key」。

Hacker News 上的「We updated our RSA SSH host key (github.blog)」這邊有人提到官方文件 (原文裡面也有提到),裡面會列出對應的 key:「GitHub's SSH key fingerprints」。

只是看起來這些大公司依然對 DNSSEC + SSHFP 這樣的組合沒興趣...

在 Hacker News 上看到幾個 Key-Value Store 軟體

Hacker News 上看到「Redis vs. KeyDB vs. Dragonfly vs. Skytable」這篇,裡面介紹了四套 key-value store 軟體:

  • Redis:這個應該不太需要介紹...
  • KeyDBSnapchat 搞出來的 Redis clone,主要的賣點是 multi-threading。
  • Dragonfly:宣稱地球上最快,但作者跑不出來,下面的討論有人提到 Dragonfly 在更多的 CPU 資源效能就會更好。
  • Skytable:作者測出來最快的。

裡面看起來都蠻有趣的,可以追起來看看發展的情況,但如果真的要的用的話,應該還是先以 Redis 為主,穩定度以及功能還是重點...

SSH 的 StrictHostKeyChecking=accept-new

OpenSSH 在連到新的 host 時會跳出 key fingerprint 的資訊讓使用者確認,有時候為了自動化會用 StrictHostKeyChecking=no 避開,在 Lobsters Daily 上則看到了新的選項可以用,StrictHostKeyChecking=accept-new

就如同選項的名字所描述的,查了一下 OpenSSH Release Notes 可以看到這是在 OpenSSH 7.5 導入的參數,是在 March 20, 2017 引入的:

* ssh(1): expand the StrictHostKeyChecking option with two new settings. The first "accept-new" will automatically accept hitherto-unseen keys but will refuse connections for changed or invalid hostkeys. This is a safer subset of the current behaviour of StrictHostKeyChecking=no. The second setting "off", is a synonym for the current behaviour of StrictHostKeyChecking=no: accept new host keys, and continue connection for hosts with incorrect hostkeys. A future release will change the meaning of StrictHostKeyChecking=no to the behaviour of "accept-new". bz#2400

對於一些自動化的流程應該夠用了,不需要到用 no 完全關掉。

翻了「Ubuntu – Package Search Results -- openssh-client」可以看到 18.04 之後都是 7.5 之後的版本了,支援度應該是沒什麼太大問題...