用 PGP 保護代碼完整性(一): 基本概念和工具
在本系列文章中,我們將深度探討如何使用 PGP 確保軟體完整性。這些文章將為工作於自由軟體項目的開發者提供實用指南,並且將包含以下主題:
- PGP 基礎和最佳實踐
- 如何用 Git 使用 PGP
- 如何保護你的開發者賬戶
我們使用與「Freedom」含義相同的詞項 「Free」,但這個系列中列出的指南也可以被任何其它類型的依賴於分散式團隊開發者貢獻的軟體中。如果你編寫進入公共源倉庫的代碼,你可以從了解和遵循這篇指南中受益。
結構
每節分為兩個部分:
- 適用於你項目需求的清單
- 形式自由的考慮事項的列表,解釋這些決定取決於什麼,並伴隨著配置指令
清單優先順序
每個清單中各項包含著優先順序,用來幫助指導你的決定:
- (必要)該項一定要排在考慮事項列表的前面。如果沒有這樣做,它們將給提交到開源項目中的代碼帶來高風險。
- (推薦)包含該項將提升整體安全性,但會影響你與工作環境的交互方式,並且可能需要學習新的習慣或者放棄舊的習慣。
記住,這些只是指導。如果你感到這些優先順序不能反映你項目提交的安全,你應該根據自己的需要調整它們。
PGP 基本概念和工具
清單
- 理解 PGP 在自由軟體開發中的作用 (必要)
- 理解 公鑰密碼學 的基礎知識 (必要)
- 理解 PGP 加密和簽名的不同 (必要)
- 理解 PGP 密鑰身份 (必要)
- 理解 PGP 密鑰有效性 (必要)
- 安裝 GnuPG 工具(版本 2.x) (必要)
考慮事項
自由軟體社區長期依賴於 PGP 確保它生產的軟體產品的真實性和完整性。你可能沒有注意到,但無論你是一個 Linux 、Mac 和 Windowas 用戶,你都曾依賴 PGP 來確保你電腦環境的完整性:
- Linux 發行版依賴 PGP 來確保當二進位或者原代碼包從被生產出來到被終端用戶安裝之間沒被更改過
- 自由軟體項目通常會伴隨發行軟體的存檔提供分離的 PGP 簽名,使得下游的項目可以在把下載的版本集成到自己的分散式下載之前,驗證下載版本的完整性。
- 自由軟體項目通常依賴代碼本身的 PGP 簽名來跟蹤起源,並驗證項目開發者提交的代碼的完整性
這與工作於專有平台的程序員使用的開發者證書或代碼簽名機制非常相似。實際上,這兩種技術背後的核心概念非常相似 —— 儘管它們在實現的技術層面和它們委託信任方式的大多不同。PGP 不依賴於集中式認證機構,而是讓每個用戶為每個證書賦予自己的信任。
我們的目標是使你的項目通過使用 PGP 來進行代碼起源和完整性追蹤,遵循最佳實踐並遵守基本的安全預防措施。
極其基本的 PGP 操作概括
你不需要知道 PGP 如何工作的具體細節 —— 理解核心概念足以成功地達到我們的目的。PGP 依賴於公鑰密碼學來將明文轉換為密文。這個過程需要兩種不同的密鑰:
- 公鑰,被所有人知道
- 私鑰,只被擁有者知道
加密
對加密來說,PGP 使用擁有者的公鑰創造一條只能通過擁有者私鑰解密的消息:
- 發送者生成一個隨機的加密密鑰(「會話密鑰」)
- 發送者使用該會話密鑰(使用對稱演算法)加密內容
- 發送者使用接收者的 PGP 公鑰加密會話密鑰
- 發送者向接收者發送加密後的內容和加密後的會話密鑰
要解密:
- 接收者使用他們的 PGP 私鑰解密會話密鑰
- 接收者使用會話密鑰解密消息的內容
簽名
為了創建簽名,PGP 私鑰或公鑰會以相反的方式使用:
- 簽名者生成內容的校檢和哈希
- 簽名者使用自己的 PGP 私鑰來加密該校檢和
- 簽名者伴隨內容提供加密後的校檢和
要驗證簽名:
- 驗證者生成自己的內容校檢和哈希
- 驗證者使用簽名者的 PGP 公鑰來解密提供的校檢和
- 如果校檢和匹配,就驗證了內容的完整性
結合使用
通常,加密消息也被發送者自己的 PGP 密鑰簽名。無論何時使用加密消息,這應當是默認的,因為沒有認證的加密沒有很大意義(除非你是一個告密者或秘密代理並且需要可行的可否認性)
理解密鑰身份
每個 PGP 密鑰必須有一個或多個與之關聯的身份。通常,「 身份 」指的是以下格式中的人物全名和郵件地址:
Alice Engineer <alice.engineer@example.com>
有時也會在括弧中包含說明,來告訴終端用戶關於該特定密鑰的更多信息:
Bob Designer (obsolete 1024-bit key) <bob.designer@example.com>
由於人們可以和多個職業和個人實體相關聯,因此在同一密鑰上可以有多個身份:
Alice Engineer <alice.engineer@example.com>
Alice Engineer <aengineer@personalmail.example.org>
Alice Engineer <webmaster@girlswhocode.example.net>
當使用多個身份時,其中之一將被標記為「 primary identity 」來讓檢索更簡單。
理解密鑰有效性
為了能使用其他人的公鑰來加密或驗證,你需要確保它確實屬於正確的人(Alice)而不屬於冒牌的(Eve)。在 PGP 中,這被稱為「密鑰有效性」:
- 有效性: 完全 -- 意味著非常確認該密鑰屬於 Alice
- 有效性: 臨界 -- 意味著大致確認該密鑰屬於 Alice
- 有效性: 未知 -- 意味著不確認該密鑰是否屬於 Alice
Web of Trust (WOT) 與 Trust on First Use (TOFU)
PGP 使用了一種信任委託機制叫「Web of Trust」。它的核心是嘗試替代 HTTPS/TLS 世界中對集中式認證機構的需求。PGP 把這個責任交給了每個用戶,而不是各種軟體開發商來決定誰應該是你的可信認證實體。
不幸的是,很少有人理解 Web of Trust 的是如何工作的,能使用它的人更少。它仍然是 OpenPGP 規範的一個重要方面,但 GnuPG 的近期版本(2.2 及以上)已經實現了一種替代機制叫「Trust on First Use」(TOFU)。
你可以把 TOFU 當作類似 SSH 的信任方式。使用 SSH,當你第一次連接到遠程系統,它的密鑰指紋會被記錄和保存。如果將來密鑰改變,SSH 客戶端將會提醒你並拒絕連接,迫使你決定是否信任已改變的的密鑰。
同樣,當你第一次導入某人的 PGP 密鑰,它被假定可信。如果在將來的任何時候,GnuPG 碰巧發現另一同樣身份的密鑰,過去導入的密鑰和新密鑰都將被標記為無效,並且你需要手動指出保留哪個。
安裝 OpenPGP 軟體
首先,理解 PGP、OpenPGP、GnuPG 和 gpg 之間的不同很重要:
- PGP (「Pretty Good Privacy」) 是最初商業軟體的名字
- OpenPGP 是與最初 PGP 工具兼容的 IETF 標準
- GnuPG (「Gnu Privacy Guard」)是實現了 OpenPGP 標準的自由軟體
- GnuPG 的命令行工具稱為 「gpg」
今天,「PGP」這個詞幾乎被普遍用來表示開放的 OpenPGP 標準,而不是最初的商業軟體,因此「PGP」和「OpenPGP」是可以互換的。「GnuPG」和「pgp」這兩個詞應該僅在提及工具時使用,而不用於它們產生的輸出或它們實現的 OpenPGP 功能。舉例:
- PGP(而非 GnuPG 或 GPG)密鑰
- PGP(而非 GnuPG 或 GPG)簽名
- PGP(而非 GnuPG 或 GPG)密鑰伺服器
理解這一點應該可以保護你免受來自你遇到的其他 PGP 用戶「實際上」不可避免的迂腐。
安裝 GnuPG
如果你正在使用 Linux,你應該已經安裝過了 GnuPG。在 Mac 上,你應該安裝 GPG-Suite,或者使用 brew
安裝 gnupg2
。在 Windows 上,你應該安裝 GPG4Win,並且為了可以工作,你可能需要調整指南中的部分命令,除非你設置了類似 Unix 的環境。對其他平台來說,你需要自行查找正確的地址來下載和安裝 GnuPG。
GnuPG 1 vs. 2
GnuPG v.1 和 GnuPG v.2 都實現了同樣的標準,但它們提供不兼容的庫和命令行工具,所以許多發行版都帶有了舊的版本 1 和最新的版本 2。你需要確保你總是使用 GnuPG v.2。
首先,運行:
$ gpg --version | head -n1
如果你看到 gpg (GnuPG) 1.4.x
,說明你正使用 GnuPG v.1。嘗試下 gpg2
命令:
$ gpg2 --version | head -n1
如果你看到 gpg (GnuPG) 2.x.x
,說明你可以繼續了。這篇指南將假設你使用 GnuPG 2.2 版本(或更新)。如果你正使用 GnuPG 的 2.0 版本,本指南中某些命令可能無效,你應該考慮安裝 GnuPG 最新的 2.2 版本
確保你總是使用 GnuPG v.2
如果你 gpg
和 gpg2
命令都有,你應該確保總是使用 GnuPG v.2,而不是舊的版本。你可以通過設置別名來確保這一點:
$ alias gpg=gpg2
你可以把它放在你的 .bashrc
中,以確保它在你使用 gpg
命令時總是被載入。
在本系列的第 2 部分中,我們將介紹生成和保護你的 PGP 主密鑰的基本步驟。
通過 Linux 基金會和 edX 的免費「Introduction to Linux」 課程了解關於 Linux 的更多信息。
作者:Konstantin Ryabitsev 譯者:kimii 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive