用 PGP 保護程式碼完整性(五):將子金鑰移到一個硬體裝置中

2019-01-05 00:15:00

在這個系列教學中,將為你提供使用 PGP 和保護你的私鑰的最佳體驗。

在本系列教學中,我們將提供一個使用 PGP 的實用指南。如果你沒有看過前面的文章,你可以通過下面的連結去檢視。在這篇文章中,我們將繼續討論如何保護你的金鑰,談一談將你的子金鑰移到一個專門的硬體裝置中的一些技巧。

清單

  • 取得一個 GnuPG 相容的硬體裝置(必要)
  • 設定 GnuPG 在裝置上工作(必要)
  • 設定使用者和管理員的 PIN(必要)
  • 移動子金鑰到裝置中(必要)

考慮事項

雖然現在主金鑰已經不用擔心洩露或失竊了,但子金鑰仍然在你的家目錄中。任何得到它的人都能夠解密你的通訊或假冒你的簽名(如果他們知道金鑰的密碼)。並且,每次執行一個 GnuPG 操作都要將金鑰載入到作業系統記憶體中,這將使一些更高階的惡意軟體有機會得到你的金鑰(想想 Meltdown 和 Spectre)。

完全保護金鑰的最好方式就是,將它移到一個專門的硬體裝置中,這種硬體裝置是一個可操作的智慧卡。

智慧卡的好處

一個智慧卡包含一個加密晶片,它能夠儲存私鑰,並且直接在智慧卡內部執行秘密操作。因為金鑰內容從來沒有離開過智慧卡,計算機作業系統並不能檢索你插入的智慧卡上的私鑰。這與前面用於備份目的的加密 USB 儲存是不同的 —— 雖然 USB 裝置也是插入並解密的,但作業系統是能夠去存取私鑰內容的。使用外接的加密 USB 媒介並不能代替智慧卡裝置的功能。

智慧卡的一些其它好處:

  • 它們很便宜且易於獲得
  • 它們小巧且易於攜帶
  • 它們可以用於多種裝置上
  • 它們中的很多都具有防篡改功能(取決於製造商)

可用的智慧卡裝置

智慧卡最初是嵌入到真實錢包大小的卡中,故而得名智慧卡。你肯定可以買到並使用 GnuPG 功能的智慧卡,並且它們是你能得到的最便宜的可用裝置之一。但是,事實上智慧卡有一個很重要的缺點:它們需要一個智慧卡讀卡器,只有極小數的筆記型電腦上有這種讀卡器。

由於這個原因,製造商開始推出小型 USB 裝置,它的大小和 U 盤類似,內建有微型智慧卡,並且在晶片上簡單地實現了智慧卡協定特性。下面推薦幾個這樣的裝置:

  • Nitrokey Start:開源硬體和自由軟體,可用於 GnuPG 的最便宜的選擇之一,但是額外的安全特性很少。
  • Nitrokey Pro:類似於 Nitrokey Start,它提供防篡改及更多的安全特性(但沒有 U2F,具體檢視指南的 U2F 節)。
  • Yubikey 4:專利硬體和軟體,但比 Nitrokey Pro 便宜,並且可以用在最新的筆記型電腦上的 USB-C 介面;也提供像 U2F 這樣的額外的安全特性。

我們推薦選一個同時具備智慧卡功能和 U2F 的裝置,在寫這篇文章時,只能選擇 Yubikey 4。

設定智慧卡裝置

你的智慧卡裝置插入任何一台現代的 Linux 或 Mac 工作站上都應該能正常工作。你可以通過執行如下的命令去驗證它:

$ gpg --card-status

如果你沒有收到錯誤,有一個完整的卡列表,就表示一切正常。不幸的是,排除為什麼裝置不能正常工作的所有可能原因,已經超出了本指南的範圍。如果你的智慧卡使用 GnuPG 時有問題,請通過你的作業系統的常見支援通道尋求支援。

PIN 不一定是數位

注意,儘管名為 “PIN”(暗示你它必須是一個“數位”),不論是使用者 PIN 還是管理員 PIN 都不必非要是數位。

當你收到一個新裝置時,它可能設定有一個預設的使用者和管理員 PIN,對於 Yubikey,它分別是 12345612345678。如果它們的 PIN 不是預設的,請檢視裝置附帶的說明書。

快速設定

為設定你的智慧卡,你需要使用 GnuPG 選單系統,因此這裡並沒有更方便的命令列開關:

$ gpg --card-edit[...omitted...]gpg/card> adminAdmin commands are allowedgpg/card> passwd

你應該去設定使用者 PIN (1)、管理員 PIN (3)、和重置碼 (4)。請確保把它們記錄並儲存到一個安全的地方 —— 尤其是管理員 PIN 和重置碼(它允許你去擦除整個智慧卡內容)。你很少使用到管理員 PIN,因此如果你不記錄下來,很可能會忘掉它。

返回到智慧卡主選單,你也可以設定其它值(比如名字、性別、登入日期、等等),但是這些都不是必需的,一旦你的智慧卡丟失了,將導致額外的資訊洩露。

將子金鑰移到你的智慧卡中

退出卡選單(使用 q 命令)儲存所有更改。接下來,我們將你的子金鑰移到智慧卡中。將需要用到你的 PGP 金鑰的密碼,在大多數的智慧卡操作中都將用到管理員 PIN。記住,那個 [fpr] 表示你的金鑰的完整的 40 個字元的指紋。

$ gpg --edit-key [fpr]Secret subkeys are available.pub  rsa4096/AAAABBBBCCCCDDDD    created: 2017-12-07  expires: 2019-12-07 usage: C    trust: ultimate      validity: ultimatessb  rsa2048/1111222233334444    created: 2017-12-07  expires: never usage: Essb  rsa2048/5555666677778888    created: 2017-12-07  expires: never usage: S[ultimate] (1). Alice Engineer <[email protected]>[ultimate] (2)  Alice Engineer <[email protected]>gpg>

使用 --edit-key 再次進入到選單模式,你將注意到那個金鑰清單有一點小差別。從現在開始,所有的命令都是在這個選單模式下執行,它用 gpg> 提示符來表示。

首先,我們來選擇移到智慧卡中的金鑰 —— 你可以通過鍵入 key 1(它表示選擇清單中的第一個金鑰)來實現:

gpg> key 1

這個輸出會有一點細微的差別:

pub  rsa4096/AAAABBBBCCCCDDDD    created: 2017-12-07  expires: 2019-12-07 usage: C    trust: ultimate      validity: ultimatessb* rsa2048/1111222233334444    created: 2017-12-07  expires: never usage: Essb  rsa2048/5555666677778888    created: 2017-12-07  expires: never usage: S[ultimate] (1). Alice Engineer <[email protected]>[ultimate] (2)  Alice Engineer <[email protected]>

注意與金鑰對應的 ssb 行旁邊的 * —— 它表示這是當前選定的金鑰。它是可切換的,意味著如果你再次輸入 key 1,這個 * 將消失,這個金鑰將不再被選中。

現在,我們來將金鑰移到智慧卡中:

gpg> keytocardPlease select where to store the key:  (2) Encryption keyYour selection? 2

由於它是我們的 [E] 金鑰,把它移到加密區中是有很有意義的。當你提交了你的選擇之後,將會被提示輸入你的 PGP 金鑰的保護密碼,接下來輸入智慧卡的管理員 PIN。如果命令沒有返回錯誤,表示你的金鑰已經被移到智慧卡中了。

重要: 現在再次輸入 key 1 去取消選中第一個金鑰,並輸入 key 2 去選擇 [S] 金鑰:

gpg> key 1gpg> key 2gpg> keytocardPlease select where to store the key:  (1) Signature key  (3) Authentication keyYour selection? 1

你可以使用 [S] 金鑰同時做簽名和驗證,但是我們希望確保它在簽名區,因此,我們選擇 (1)。完成後,如果你的命令沒有返回錯誤,表示操作已成功。

最後,如果你建立了一個 A 金鑰,你也可以將它移到智慧卡中,但是你需要先取消選中 key 2。完成後,選擇 q

gpg> qSave changes? (y/N) y

儲存變更將把你的子金鑰移到智慧卡後,把你的家目錄中的相應子金鑰刪除(沒有關係,因為我們的備份中還有,如果更換了智慧卡,你需要再做一遍)。

驗證移動後的金鑰

現在,如果你執行一個--list-secret-keys 操作,你將看到一個稍有不同的輸出:

$ gpg --list-secret-keyssec#  rsa4096 2017-12-06 [C] [expires: 2019-12-06]     111122223333444455556666AAAABBBBCCCCDDDDuid           [ultimate] Alice Engineer <[email protected]>uid           [ultimate] Alice Engineer <[email protected]>ssb>  rsa2048 2017-12-06 [E]ssb>  rsa2048 2017-12-06 [S]

ssb> 的輸出中的 > 表示子金鑰僅在智慧卡上有效。如果你進入到你的金鑰目錄中,檢視目錄的內容,你將會看到那個 .key 檔案已經被存根替換:

$ cd ~/.gnupg/private-keys-v1.d$ strings *.key

這個輸出將包含一個影子私鑰,它表示那個檔案僅是個存根,真正的內容在智慧卡中。

驗證智慧卡的功能

驗證智慧卡能否如期正常執行,你可以通過建立一個簽名來驗證:

$ echo "Hello world" | gpg --clearsign > /tmp/test.asc$ gpg --verify /tmp/test.asc

首次執行這個命令時將詢問你智慧卡的 PIN,在你執行 gpg —verify 之後,它將顯示 “Good signature”。

祝賀你,你已經成功將竊取你的開發者數位身分變得更加困難了!

其它常見 GnuPG 操作

下面是使用你的 PGP 金鑰需要做的一些常見操作的快速指南。

在下面的所有命令中,[fpr] 表示你的金鑰指紋。

掛載主金鑰離線儲存

下面的一些操作將需要你的主金鑰,因此首先需要去掛載你的主金鑰離線儲存,並告訴 GnuPG 去使用它。首先,找出媒介掛載路徑,可以通過檢視 mount 命令的輸出找到它。接著,設定你的 GnuPG 目錄為你的媒介上備份的目錄,並告訴 GnuPG 將那個目錄做為它的家目錄:

$ export GNUPGHOME=/media/disk/name/gnupg-backup$ gpg --list-secret-keys

確保你在輸出中看到的是 sec 而不是 sec#(這個 # 表示金鑰不可用,仍然使用的是慣常的那個 Home 目錄)。

更新你慣常使用的那個 GnuPG 工作目錄

在你的離線儲存上做了任何更改之後,你應該將這些更改同步應用到你慣常使用的工作目錄中:

$ gpg --export | gpg --homedir ~/.gnupg --import$ unset GNUPGHOME
延長金鑰過期日期

我們建立的主金鑰的預設過期日期是自建立之日起兩年後。這樣做都是為安全考慮,這樣將使淘汰金鑰最終從金鑰伺服器上消失。

延長你的金鑰過期日期,從當前日期延長一年,只需要執行如下命令:

$ gpg --quick-set-expire [fpr] 1y

如果為了好記住,你也可以使用一個特定日期(比如,你的生日、1 月 1 日、或加拿大國慶日):

$ gpg --quick-set-expire [fpr] 2020-07-01

記得將更新後的金鑰傳送到金鑰伺服器:

$ gpg --send-key [fpr]
吊銷身份

如果你需要吊銷一個身份(比如,你換了雇主並且舊的郵件地址不再有效了),你可以使用一行命令搞定:

$ gpg --quick-revoke-uid [fpr] 'Alice Engineer <[email protected]>'

你也可以通過使用 gpg --edit-key [fpr] 在選單模式下完成同樣的事情。

完成後,記得將更新後的金鑰傳送到金鑰伺服器上:

$ gpg --send-key [fpr]

下一篇文章中,我們將談談 Git 如何支援 PGP 的多級別整合。

通過來自 Linux 基金會和 edX 的免費課程 “Linux 入門”學習更多 Linux 知識。