對 YubiKey 5 的 side-channel attack

Hacker News Daily 上看到的「EUCLEAK Side-Channel Attack on the YubiKey 5 Series (ninjalab.io)」,原文在「EUCLEAK」這邊。

YubiKey 5 的攻擊,攻擊需要能夠碰到實體的 key,透過 side-channel 取得 ECDSA secret key 進而複製:

The attack requires physical access to the secure element (few local electromagnetic side-channel acquisitions, i.e. few minutes, are enough) in order to extract the ECDSA secret key. In the case of the FIDO protocol, this allows to create a clone of the FIDO device.

新版的 firmware 解掉了這個問題:

The new YubiKey firmware 5.7 update (May 6th, 2024) switches the YubiKeys from Infineon cryptographic library to Yubico new cryptographic library. To our knowledge, this new cryptographic library is not impacted by our work.

但是官方文件上面也有提到 YubiKey 不支援 firmware 升級:「YubiKey Firmware is Not Upgradable」,對於安全性有高要求的人可能要聯絡 Yubico 看能不能換了...

另外手上的 YubiKey 從外觀不太好認,我是用 USB 的 Device ID 認的,發現官方有列出來,在 Linux 下可以用 lsusb 看到,Windows 應該是裝置管理員之類的地方可以看:「YubiKey USB ID Values」。

AWS KMS 支援 ECDH

看到「Announcing AWS KMS Elliptic Curve Diffie-Hellman (ECDH) support」這篇的介紹,AWS KMS 支援 ECDH 了。

AWS 的文件「DeriveSharedSecret」這邊可以看到就是在不將 private key 暴露出來的情況下得到 ECDH 產生的 shared secret:

The private key in your KMS key pair never leaves AWS KMS unencrypted. DeriveSharedSecret returns the raw shared secret.

翻了一下其他兩個雲的 Cloud HSM 類服務,好像沒有看到 ECDH 的,不過如果是實際硬體 HSM 的話,Azure Dedicated HSM 似乎有支援,可以在 FAQ 這邊看到:

Dedicated HSM service provisions Thales Luna 7 HSM appliances.

Cryptography (ECDSA, ECDH, Ed25519, ECIES) with named, user-defined, and Brainpool curves, KCDSA

AWS KMS 畢竟是軟體基底的,要支援什麼演算法可以直接加...

在 PostgreSQL 裡,當 UUID 當作 Primary Key 時要怎麼處理

繼續清 tab,在「PostgreSQL and UUID as Primary Key (maciejwalkowiak.com)」這邊看到的,原文是討論 PostgreSQL 要怎麼處理 PK 是 UUID 的情況:「PostgreSQL and UUID as primary key」。

文章開頭作者就說了,這篇不是要戰 PK 要不要用 UUID,而是已經決定要用了 (i.e. 通常不是你決定的),在接手以後要怎麼用比較好:

Considering the size of UUID it is questionable if it is a right choice, but often it is not up to us to decide.

This article does not focus on "if UUID is the right format for a key", but how to use UUID as a primary key with PostgreSQL efficiently.

首先是 PostgreSQL 從 8.3 版 (2008 年) 就支援 UUID 的資料型態了,這點從 release note 可以看到:「PostgreSQL 8.3.0」,所以要當 PK 的話沒什麼道理不考慮他。

UUID 的空間上就是 128-bit data (16 bytes),相比於 TEXT 會省蠻多的,尤其 PK 常常會被其他表格 reference 到 (像是 foreign key) 會在其他表格也省下來:

Table that uses text is 54% larger and the index size 85% larger.

第二點則是考慮到 UUID 本身的特性,以前的 UUID 因為是亂數生成的 (通常會用 UUIDv4),對寫入 B-tree 類的資料結構不是很有效率,改用 UUIDv7 (差不多是這兩年陸陸續續發展出來的規格) 會得益於與 timestamp 有關,對 B-tree 寫入的效率會好很多:

Random UUIDs are not a good fit for a B-tree indexes - and B-tree index is the only available index type for a primary key.

B-tree indexes work the best with ordered values - like auto-incremented or time sorted columns.

UUID - even though always looks similar - comes in multiple variants. Java's UUID.randomUUID() - returns UUID v4 - which is a pseudo-random value. For us the more interesting one is UUID v7 - which produces time-sorted values. It means that each time new UUID v7 is generated, a greater value it has. And that makes it a good fit for B-Tree index.

作者的測試可以看到寫入速度與 UUIDv4 相比比快不少:

BUT we can clearly see, that inserting UUID v7 is ~2x faster and inserting regular UUID v4.

總結來說,當 PK 已經決定是 UUID 後,主要就是這兩個重點可以注意的,當然 Hacker News 上更熱鬧的是兩派人馬在吵要用 integer 類的 SERIAL/BIGSERIAL 還是用 UUID,那又是另外一個話題了...

如果早個二十年前對 memory size 斤斤計較的情況下,答案鐵定是 integer 類的,但年代不同了...?

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 了。