美國法院可以強制公司交出 SSL Private Key...

前幾天解密的文件證實了先前的傳言:美國法院可以以協助犯罪搜查的名義,強制商業公司交出 SSL Private Key 給 FBI,並且可以用「偵查犯罪中」的理由要求公司不得公開這件事情。

報導在這:「Edward Snowden’s E-Mail Provider Defied FBI Demands to Turn Over Crypto Keys, Documents Show」,解密的文件 (整個系列的文件) 則在「Redacted Pleadings Exhibits 1 23」這邊可以讀到。

Edward Snowden 的 E-mail 服務提供商 Lavabit 在七月時被法院要求配合調查,其中被要求交出 SSL Private Key:

A week later, prosecutors upped the ante and obtained the search warrant demanding “all information necessary to decrypt communications sent to or from the Lavabit e-mail account [redacted] including encryption keys and SSL keys.”

而且「交出 SSL key 這件事情」不得公開:

The judge also rejected Lavabit’s motion to unseal the record. “This is an ongoing criminal investigation, and there’s no leeway to disclose any information about it.”

而 Lavabit 最後決定以紙本形式提供:

In an interesting work-around, Levison complied the next day by turning over the private SSL keys as an 11 page printout in 4-point type. The government, not unreasonably, called the printout “illegible.”

在法院要求提供電子格式後,Levison (Lavabit 的頭) 決定讓 Lavabit 停止服務,同時因為受限封口令,網站上只能寫得很隱晦,表達對美國的不信任:

這件事情預定要到第四巡迴庭去打:「Let's rally for Lavabit to fight for the privacy rights of the American people. | Rally.org」。

Amazon CloudFront 上 Protected Content 的 URL Sign...

Amazon CloudFront 也可以設定要簽名才能抓檔案,只是 URL Sign 設計的觀念跟 Amazon S3 完全不一樣,這不一致的調調很... 詭異...

大致上有這些差異:

  • Amazon S3 用的是 HMAC-SHA1 的機制簽名 (shared secret,也就是 Amazon S3 與你都有同一把 key),而 Amazon CloudFront 則是用 RSA key 簽名 (public key,也就是 Amazon CloudFront 存放 public key,你自己存放 private key)。
  • 也因為是使用 RSA key,有人會誤解跟 Amazon EC2 用的 RSA key 相同。但實際上需要在 Security Credentials 頁裡設,有專門對 Amazon CloudFront 用的 RSA key 的段落。
  • 自己對 Base64 編碼再處理,避開使用 += 以及 /。但不是有標準可以用嗎,為什麼要自己發明呢...
  • 引入 Policy 的彈性機制,不僅可以對時間控制,也可以對 IP address 控制,但 Policy 這是帶在 URL 裡傳進去的... 你可以看到我的程式碼內產生出 $json_str 後簽完名帶到 URL 內了。

官方的 CloudFront Signed URLs in PHP 這篇的範例程式碼其實很清楚了,要直接拿去用其實也沒麼問題。我自己整理後是這樣:

<?php

$key_pair_id = 'APKA...';
$pem_file = '';
$resource = 'http://test2-cdn.gslin.org/test.txt';

$expires = time() + 3600;

$json_str = json_encode(
    array(
        'Statement' => array(
            array(
                'Resource' => $resource,
                'Condition' => array(
                    'DateLessThan' => array(
                        'AWS:EpochTime' => $expires
                    )
                )
            )
        )
    ),
    JSON_UNESCAPED_SLASHES
);

$buf = file_get_contents($pem_file);
$key = openssl_get_privatekey($buf);

openssl_sign($json_str, $signed_policy, $key, OPENSSL_ALGO_SHA1);

openssl_free_key($key);

$signature = str_replace(
    array('+', '=', '/'),
    array('-', '_', '~'),
    base64_encode($signed_policy)
);

echo "${resource}?",
    "Expires=${expires}&",
    "Signature=${signature}&",
    "Key-Pair-Id=${key_pair_id}\n";

反正你搞不太懂 Amazon 為什麼要這樣設計的... =_=

各種密碼破解速度...

oclHashcat-plus 提供了透過 GPU 破解的 benchmark 數據:

可以看到 PBKDF2、sha512crypt $6$ 以及 bcrypt $2a$ 的速度慢得很漂亮 XD 不過 SHA512 的速度比 SHA256 慢不少倒是頗意外...

PBKDF2 的使用率很高 (因為無線網路 WPA/WPA2 的規格),所以各語言的普及率也高不少,如果要找個標準來用的話,PBKDF2 相當不錯...

SSL/TLS 的 Perfect Forward Secrecy...


寫這篇順便測試 MathJax 的效果...

因為 NSA 的惡搞,這陣子 PFS (Perfect Forward Secrecy) 突然被拿出來討論:

在講 PFS 前,得先講 Diffie-Hellman key exchange (D-H)。

D-H 是利用這個等式:

$$(g^a)^b \equiv (g^b)^a \mod p$$

其中 \(p\) 是大質數,而 \(g\) 是 \(p\) 的 primitive root (即不存在任何 \(n < p\) 可以使得 \(g^n \equiv 1 \mod p\))。 而因為當 \(p\) 夠大時,要從 \(g^a \mod p\) 計算 \(a\) 就是離散對數問題,而離散對數問題是已知沒有有效率計算的問題,所以我們會假定當 \(p\) 夠大時,傳輸 \(g^a \mod p\) 是無法用合理資源計算得知 \(a\)。

因此,Alice 與 Bob 就可以產生自己的 private secret \(a\) (Alice) 與 \(b\) (Bob),計算出 \(g^a\) 與 \(g^b\) 後公開傳輸給對方,當 Bob 收到 Alice 提供的 \(g^a\) 時就計算 \((g^a)^b \equiv g^{ab} \mod n\),而 Alice 收到 Bob 提供的 \(g^b\) 後可以計算 \((g^b)^a \equiv g^{ba} \equiv g^{ab} \mod n\)。

而攻擊者只拿到公開的 \(g^a\) 與 \(g^b\) 以及 \(g\),無法計算出 \(g^{ab}\),於是就雙方就建立一組 shared secret 了。

回到 SSL/TLS 的問題上,由於 RSA 加解密的速度並不快,所以 SSL/TLS 是在 RSA 的保護下交換 RC4 或是 AES 所需要的金鑰 (key)。

交換 key 這件事情除了可以直接交換以外,還可以利用 D-H 交換。

D-H 交換可以確保當 RSA key 被破解時還要再破每個 session 的 D-H 所產生出來的 key,而直接交換的話,只要破一把 RSA key 就可以解出所有 traffic 了。

而 PFS 會被提出來,是因為目前消息指出 NSA 其實有在錄下 SSL/TLS 流量,等哪天有機會取得 RSA key 的時候 (無論是硬解,或是其他方式),就有機會能夠一次破一卡車資料... (因為目前大部分的 SSL/TLS 流量都沒有上 PFS)

雖然 PFS 會慢一些,不過已經確認 NSA 打算來搞了,所以還是乖乖加上去吧... @_@

把 MySQL MyISAM 換到 Galera Cluster 的 InnoDB 上...

在「Switching from MySQL/MyISAM to Galera Cluster」這邊看到一個 script 可以檢查 MySQL MyISAM 換到 InnoDB,而且預定要換成 Galera Cluster 時的問題。

常見的問題都有檢查到,還蠻有用的:

  • 針對沒有 Primary Key 的表格提出警告,讓管理者規劃補上 Primary Key。
  • 針對 MyISAM 換成 InnoDB 後造成 Primary Key 太長的表格提出警告,讓管理者想辦法修改。

Galera Cluster 無法處理沒有 Primary Key 表格的刪除動作:(可以參考「MariaDB Galera Cluster - Known Limitations」這邊的說明)

DELETE operation is unsupported on tables without primary key. Also rows in tables without primary key may appear in different order on different nodes. Don't use tables without primary key.

不過每個表格都要有 Primary Key 並不難,因為如果有正規化時通常都會達到目標。就算不去用他也還是可以設計一個 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT 放著。(過大的時候再換成 BIGINT UNSIGNED)

有人把 Twitter 官方 App 的 OAuth API Key 解出來了...

在「Twitter OAuth API Keys Leaked」看到有人把 Twitter 官方應用程式的 API key 給解出來了,包括所有平台 XD

這件事情在技術上沒辦法避免,就跟 DRM 技術一樣... 不過也不用擔心,這些 key 與 secret 沒有安全問題,在 OAuth 設計上只是拿來識別 client 用,而用這些 key 的好處是 Twitter 不會限制這些 client 的 API 呼叫次數... XD

這完全怒了啊 XDDD

用 Percona XtraBackup 備份時用 compact 模式節省空間...

在「Feature preview: Compact backups in Percona XtraBackup」看到的,2.1 版會導入 compact backup 節省備份出來的空間 (目前是 2.0):

As you may know InnoDB PK (Primary Key) contains all data, and all secondary indexes are only subset of columns of Primary Key. So in theory we can store only PK, and re-build secondary indexes as we need. Well, now it is possible not only in theory.

secondary index 可以事後再建,所以有兩種表格會省下很多資源:

  • Index 很多的表格。
  • PK 欄位空間很大的表格 (像是用 VARCHAR(255) 當 PK)。

等出了再來研究看看對 Percona XtraDB Cluster (PXC) 重新同步可以加快多少...

對稱式加密系統的爆炸歷史 (Authenticated encryption 的問題)

在「Disasters」這邊列了不少對稱式加密系統 (secret-key cryptography) 爆炸的歷史,其中提到了很多 Encrypt 與 MAC 結合時的問題 (Authenticated encryption)。另外 Colin Percival 在 2009 年的時候有寫了一篇為什麼要用 Encrypt-then-MAC 的文章:「Encrypt-then-MAC」,當時 Colin Percival 寫的時候大家還是不能理解,但現在回頭看上面的爆炸歷史應該就清楚很多了 XDDD

SSH 協定是使用 Encrypt-and-MAC (傳輸「密文」與「明文的 MAC 值」)。在 2008 年時 SSH 使用 CBC 模式時會有安全問題:對 128bits CBC mode system (像是 aes128-cbc),任意位置的 32bits 有 2-18 的機會可以解出原文。(CVE-2008-5161,論文是「Plaintext Recovery Attacks Against SSH」)

TLS 1.0 (SSLv3) 使用 MAC-then-Encrypt (傳輸「明文與明文的 MAC 值」加密後的結果)。1999 年就知道這個方法不可靠,不過到了 2011 年時才被拿出來示範,也就是 BEAST attack。(CVE-2011-3389,在 ekoparty Security Conference 上的「表演」:「BEAST: Surprising crypto attack against HTTPS」,連結1連結2)

OpenSSLGnuTLS 所實作的 DTLS 在 2011 年也被炸到,其中 OpenSSL 是 100% plaintext recovery,GnuTLS 是 4%。(CVE-2012-0390,論文是「Plaintext-Recovery Attacks Against Datagram TLS」)

而 Encrypt-then-MAC (傳輸「密文」與「密文的 MAC」) 是三者裡面最不容易出包的作法,而且被證明 Provable security:Encrypt 與 MAC 所用的 crypto system 的安全強度不會因為 Encrypt-then-MAC 而減少。而這也是 IPSec 的作法。

附帶一提,其中 Provable security 這個詞,並非表示「可被證明是安全的」,在「In defense of Provable Security」這篇文章裡有比較完整的說明。通常是指安全強度不會因為這個系統而降低:以 Encrypt-then-MAC 的例子來說,如果 Encrypt 的部份用 DES,或是 MAC 用 CRC32,那麼 Encrypt-then-MAC 並不會提供更強的安全性...

總而言之,MAC-then-Encrypt 與 Encrypt-and-MAC 的方式要小心才能避免各種攻擊 (像是不能用 CBC mode),而 Encrypt-then-MAC 可以讓設計協定的人放鬆到「只要 Encrypt 與 MAC 都夠強」系統就沒問題。在 Authenticated encryption 裡提到的 ISO/IEC 19772:2009 支援六個模式,有些有專利問題,有些演算法看起來就很複雜 (於是就容易出包),其中 Encrypt-then-MAC 看起來是個還不錯的方案...

把 PEM Private Key 檔轉成 SSH Public Key 格式...

RSA 中,單獨靠 Private Key 是無法算出 Public Key 的,不過在 PEM 檔裡因為都有紀錄,所以可以取出:

openssl rsa -in aws.pem -pubout

不過取出的格式需要再轉一次讓 OpenSSH 可以吃:(參考「Convert pem key to ssh-rsa format」這篇的方法)

ssh-keygen -f aws.pub -i -m PKCS8

雖然 ssh-keygen 不接受 - 當 stdin,但可以利用 /dev/stdin 直接串起來:

openssl rsa -in aws.pem -pubout | ssh-keygen -f /dev/stdin -i -m PKCS8

結果回頭用 Google 提供的 Chrome 就好了...

因為目前 Ubuntu 12.04 的 chromium-browser 還是 18.0,所以在「Ubuntu 上的 Chromium Stable Channel 與 Dev Channel」這篇試著裝新版的 chromium,結果發現問題不少...

stable 版本容易 core dump 掛掉,dev 版本感覺是 connection leak... 可用的 connection 變少後,網站速度卡在 parallel connection 不夠。

結果晚上被 gasolwu 說可以裝 Google 官方的版本,才發現從 Google 下載下來雖然是 deb,但安裝時會自動增加 apt key (好邪惡啊) 並且設定 apt 機制更新...

總算能用 21.0 了...