2013年12月22日 星期日

使用 GnuPG 建立你的 PGP 金鑰, 讓別人能夠私密寄信給你

[2015/12/8 補充: 讀到這篇: 15 reasons not to start using PGP 意思是說 PGP (還有 GnuPG 也類似) 不夠好, 應該改用較新的技術。 ( 新技術比較表) 以後再研究...]

[2016/12/12 補充: 電腦麻瓜嗎? 改推薦這篇更簡單很多的 直接在瀏覽器裡用 mailvelope 加密保護郵件隱私。]

捍衛私密通訊權利的最佳方式, 就是加密。 以簡訊/即時通軟體來說, 自由軟體界的大大們共同推薦 「支援 OTR 的通訊軟體」; 以 e-mail 來說, 那就非 PGP 莫屬了。 1991 年時, 反核運動人士 Phil Zimmermann 為了保護社會運動人士的私密通訊權, 撰寫了這套加密軟體並釋出。 在 linux 上, 我們採用自由軟體基金會所撰寫的版本 Gnu Privacy Guard。 你可以用 Gnu Privacy Guard (GnuPG) 建立自己的 PGP 金鑰, 方便別人能夠私密寄信給你。 本文假設讀者已有 非對稱式加解密 的粗略概念, 並且在 linux (antix 13.1) 命令列上面操作。 如果要使用圖形介面, 可安裝 kgpg 套件。 至於在 Windows 上, 可以參考 島民 No.86991066 所寫的一篇很詳盡的中文教學, 解釋如何使用 Gpg4win。 建議兩三個人同時閱讀本文, 並且在各自的電腦上實驗, 用對方的公鑰加密一段文字寄給對方。

一、 管理朋友金鑰清單

[2022/1/2] 以下某些指令需要指定 key server。 如果採用 dirmngr 來管理 key server, 會出現 「gpg: error searching keyserver: No name」 這樣很不清楚的錯誤訊息。 照著 這個問答 改設定檔, 從 log 裡面還是看不出問題出在哪裡。 好像是: 只要設定檔裡其中一個 keyserver 壞掉了, gpg 指令就會失敗。 這個 issue 的提問者指出 dirmngr 並沒有按照標準的做法連線, 但是維護者不同意。 總之, 最終棄用 dirmngr, 改回使用 --keyserver keyserver.ubuntu.com 選項。 如果這個 key server 壞掉了, 可以到 這個很長的清單 裡面去找其他的。

[2020/6/1] 在 ubuntu 18.04 上面, gnupg 會透過 dirmngr 來聯絡伺服器。 請先確認你的 ~/.gnupg/dirmngr.conf 裡面至少包含以下幾句:

standard-resolver
keyserver keyserver.ubuntu.com
keyserver keys.gnupg.net

如果需要修改, 改完後請 systemctl --user restart dirmngr 重新啟動 dirmngr。 欠了 standard-resolver 那一句, 有可能會出現 Connection refused 的錯誤 因為 dirmngr 預設好像是採用 tor 或其他奇怪的 DNS 預設值。 如果有設定檔,卻沒有指定任何 keyserver, 則有可能會出現 no data 的錯誤

只有收件那一方需要有自己的金鑰。 也就是說, 寄出私密信件比接收私密信件更簡單, 只需要有收件人的公鑰即可, 不需要建立自己的金鑰。 我們就先假想要寄信給 Linus Torvalds 或 Richard Stallman。 先到 MIT Key Server 用他們的名字分別搜尋一下。 或是改用 e-mail 搜尋: torvalds@kernel.org 或 rms@gnu.org , 這樣會比較精確。 或是在自己的電腦上用命令搜尋也可以 (底層一樣會去問 key server): gpg --keyserver keyserver.ubuntu.com --search-keys 'Linus Torvalds'gpg --keyserver keyserver.ubuntu.com --search-keys torvalds@kernel.org。 查出朋友 (預期中的收件人) 的 key ID 之後, 可以這樣從金鑰伺服器匯入朋友的金鑰: gpg --recv-keys 79BE3E4300411886 朋友的公鑰 (以及未來自己的公鑰) 會放在這裡: ~/.gnupg/pubring.gpg

當你有好幾位朋友之後, 可以這樣列出手中所有公鑰 (包含自己的): gpg --list-keys

每隔一陣子, 可以這樣更新所有朋友的公鑰: gpg --refresh-keys

也可以直接向朋友要公鑰檔 (下詳)。 如果想要把很多朋友的公鑰一口氣匯入, 可以把他們的公鑰全部都貼在同一個文字檔內, 例如叫做 keys.txt, 然後 gpg --import keys.txt

很多軟體都用 pgp/gpg 加密。 有時需會要把朋友清單從 gnupg 匯出成一個文字檔 (例如叫做 friend-pgp-keys.txt), 以便再匯入到其他軟體去: gpg --export -ao friend-pgp-keys.txt

二、 建立金鑰

建議讀者: 第一次 (沒有要公開的) 實驗先不必太認真, 隨便取個使用者 ID 與密碼即可。 等實驗全程走完, 了解所有動作之後, 再用強度夠高的密碼重新建立一對真正要用的金鑰。 下 gpg --gen-key 指令產生你的一對金鑰。 然後你會被問幾個問題: 選取金鑰種類(加密演算法)、 金鑰長度、 有效期限。 如果你用的是 linux 或 openbsd 等等開放原始碼的作業系統, 都選預設值就可以了。 如果你的作業系統是 windows 或 Mac OS... 因為 Snowden 爆料 NSA 在 RSA Windows 的亂數產生器裡, 都有植入後門; 我猜把 GPG 移植到 windows 與 Mac 的自由軟體人士應該不會那麼不小心上當; 不過為了保險起見, 還是建議選取 「DSA 和 Elgamal」 而不要選取 「RSA 和 RSA」 好了。

再來會被問到真實姓名、 電子郵件地址、 註釋。 回答完這三個問題後, 你輸入的資料會被合併成一個字串, 也就是你的 使用者 ID。 例如你若分別回答 "史奴比 Snoopy"、 "snoopy@somewhere.out.there"、 "萬人迷" (都不要打引號), 那麼你的使用者 ID 就是 "史奴比 Snoopy (萬人迷) <snoopy@somewhere.out.there>"。 這個字串就像是你自選的一組電話號碼, 或是自選的註冊代號, 但也要考慮你希望別人如何能夠搜尋到你。 所以建議拿你在網路上常用的代號來填 「註釋」。 (以我而言, 當初應該要寫 「資訊人權貴」 才對。) 其實你若不想用真名也沒人會管你; 不過 「給真名」 應該是博取網友信任的重要基礎吧。 另外, 也把你 希望公開的 其他 e-mail 帳號、 xmpp 即時通帳號、 sip 電話帳號等等都放進來吧。

三、 保管金鑰

在 linux 底下, 新建立的金鑰會放在 ~/.gnupg 資料夾裡面。 這些檔案請備份好; 但不要讓別人任意取得。 就是要把它當做鑰匙來保管咩。

強烈建議立即產生一份 「撤消憑證」 revocation certificategpg -o revoke-snoopy.asc --gen-revoke 史奴比 把產生出來的 revoke-snoopy.asc 當成像是私鑰一樣地安全保存好。 將來萬一忘記密碼, 需要撤銷時, 再拿著這個撤消憑證來照著 這一篇 撤銷你的這組金鑰。

四、 釋出你的公鑰

如同 白話非對稱式加解密 一文所解釋, 你必須把你的公鑰分享出去, 別人才能用它加密郵件, 寄私密訊息給你。 所以請: gpg -ao snoopy.asc --export 史奴比 注意: 這裡的 「史奴比」 也可以改用 「snoopy」 或 「snoopy@somewhere.out.there」 等等, 總之就是你的使用者 ID 的子字串就可以了。 這個 匯出 (export) 的動作會產生一個 snoopy.asc 裡面就是你的公鑰。 目前你先跟同組的朋友交換就好; 等你照著本文重做幾次, 覺得很滿意自己所設的使用者 ID 與密碼之後, 可以貼在自己的網頁上, 甚至 上傳到金鑰伺服器昭告天下

至於私鑰, 偶爾也會需要匯出, 例如想要把它複製到 mailvelope 去使用。 匯出私鑰的指令跟匯出公鑰類似, 只是把 --export 改成 --export-secret-keys 。 匯出私鑰時會被問密碼。 產生的檔案只有自己可以讀。 務必小心保管, 不要流出讓別人看見。

五、 加解密郵件內容或附加檔案

假設你的朋友查理布朗也建立了他專屬的金鑰, 並且把他的公鑰放在 charlie.asc 檔案裡面分享給你。 (或者假設你要寄私密信件給貴哥, 於是在 MIT Key Server 搜尋到 我的 PGP Key 並已將之存成文字檔 ckhung.asc。) 那麼你可以把他納入你的 「知道的人」 的清單: gpg --import charlie.asc 這個 「匯入 (import)」 的動作, 會把他的公鑰加入你的公鑰清單 (pubring), 這僅僅表示: 「我知道有這一號人物」 而已。 至於他知不知道你? 那就要看他有沒有匯入你的公鑰了。 又至於如果你想進一步告訴 gpg 「我信任他」, 那就要 簽署他的金鑰; 不過貴哥並沒有這麼認真地在使用 gpg, 所以從來還沒簽署過。 以上的匯入及簽署都只需要做一次。

以後要傳送加密郵件, 就很簡單了。 比方說你要把 secret.tgz 這個壓縮檔加密, 並寄給查理布朗, 那麼可以這樣下: gpg -ear 查理布朗 < secret.tgz > secret.tgz.asc 這會產生一個文字檔 secret.tgz.asc 你可以把它的內容貼到 e-mail 裡面, 寄給查理布朗。 查理布朗收到之後, 再把那段內容在他的電腦裡貼成一個文字檔 secret.tgz.asc 然後就可以 gpg -d < secret.tgz.asc > secret.tgz 回答完密碼後 (全世界只有他知道的密碼), 就會得到原始的 secret.tgz。 即使你的 e-mail 經過許多網站、 就算是 NSA 或黃世銘在這些網站佈下側錄封包的監聽爪牙, 也無法看懂你寄的文件 :-) 以上步驟適用於文字檔或各種二進位檔 (壓縮檔/圖片/聲音/影片/執行檔/...)。

六、 數位簽章與確認發文者

對一個文字檔 official-announcement.txt 簽名: gpg --clearsign official-announcement.txt 這會產生一個 official-announcement.txt.asc , 內含原始文件及簽名。 如果你有不只一對公私鑰, 可以用 -u 指定要採用哪一把私鑰籥章, 類似這樣: gpg --clearsign -u 5828A7A7 official-announcement.txt 其中的 5828A7A7 是從 gpg --list-secret-keys 列出來的 fingerprints 當中截一小段出來的。

收件人可以這樣確認: gpg --verify < official-announcement.txt.asc

七、 強制使用文字模式密碼問答

[2018/2/28] 最近 (在 lubuntu 17.10 底下) 發現在文字終端機底下 (ctrl-F1 到 ctrl-F6) 要使用 gpg 時, 會出現類似這樣的錯誤訊息:

gpg: encrypted with 2048-bit RSA key, ...
      "..."
gpg: public key decryption failed: Inappropriate ioctl for device
gpg: decryption failed: No secret key

我明明有私鑰, 但 gpg 卻連問都不問我密碼。 原來是因為 gpg 把密碼驗證的工作丟給另一支程式。 早就應該想到: 平常在圖形介面下, 會另外跳出一個視窗問密碼。 但在 VT1 到 VT6 底下, 因為無法啟動那支程式, 所以 gpg 就會失敗, 其實問題跟私鑰沒有關係。 查了 12 最後覺得最簡單的是 這個解答。 而且不需要安裝新版的 gpg2, 甚至連 pinentry-tty 套件都不必裝, 直接這樣下就可以了: gpg --pinentry-mode loopback ...

又, 如果希望 gpg-agent 忘掉它暫時記住的密碼, 可以這樣下: gpg-connect-agent reloadagent /byeecho RELOADAGENT | gpg-connect-agent。 詳見 這裡這裡

八、 更多教學文

其實網路上早就有很多教學文; 我這篇只是想把整個過程寫得比較白話而已。 此外, GPG 也可拿來製作數位簽章。 想要更深入學習, 可以參考:

  1. GnuPG Gentoo 使用者指南 (很詳盡的中文教學文)
  2. Gnu 隐私卫士 (GnuPG) 袖珍 HOWTO (翻譯自官網的簡體中文版手冊)
  3. GNU PG HOWTOs (官網文件索引, 包含許多文件的各種語言連結)
  4. GPG Tutorial (跟我的文章一樣比較口語化, 但豐富很多的英文教學文)
  5. GnuPG (GPG) In Win32 免費檔案加解密軟體概念與常用指令 (中文, 如何在 windows 底下使用指令版)

11 則留言:

  1. GnuPG Gentoo 使用者指南 (很詳盡的中文教學文)
    這個掛了

    回覆刪除
  2. "我這篇只是想把整個過程寫得比較白話而已" >> 的確, 很有幫助. 看那兩條 command (encrypt 和 decrypt) 很容易理解在做什麼.

    回覆刪除
  3. "上傳到金鑰伺服器昭告天下" 這個連結掛了.

    回覆刪除
  4. 要出現一開始那些問答要用 gpg2 --full-generate-key 才有耶

    回覆刪除
  5. 作者已經移除這則留言。

    回覆刪除
  6. 如果我有朋友給的金鑰 可是教學實在看不懂
    有甚麼辦法能直接寄信給他嗎

    回覆刪除
  7. 您好,突然打擾您,很抱歉
    針對使用GPG by Yubikey的教學
    因為我試了很多次後,還是有一個問題沒辦法有解答,所以才這麼突然的向您請教
    如果您方便的話,可否請您指點一下,我先說明一下我的問題。
    ①我是使用GPG4WIN軟體,然後產生私鑰、也成功的將私鑰匯入Yubikey。
    ②我有備份的習慣,所以我買了二隻Yubikey。
    ③我將私鑰匯入「NO.1 Yubikey」(假設編號:×××××140)
    ④然後我把相同的私鑰要匯入「NO.2 Yubikey」(假設編號:×××××136),也匯入成功了。
    ⑤我用「NO.1 Yubikey」在windows進行加/解密時,是OK的,後來我換成「NO.2 Yubikey」在同一台電腦windows進行加/解密時,卻不行、並出現訊息表示我要使用「編號:×××××140」的KEY才能夠來加解密。
    ⑥我想要問的是:我可以設定同時好幾隻(2支以上的Yubikey)在同一部電腦、同樣的私鑰來進行加/解密嗎?

    回覆刪除
    回覆
    1. 我沒有 windows 也沒有 Yubikey 耶。 胡亂猜一下:應該要把公鑰跟私鑰都匯入備份那支 (136) 才對,也許這是你失敗的原因?

      哦,等一下,搜尋到這個: https://support.yubico.com/support/solutions/articles/15000010242-can-i-duplicate-or-back-up-a-yubikey- 看來產品特性本來就是不能備份在第二枝 Yubikey 上面。 他們的備份建議在這裡: https://support.yubico.com/support/solutions/articles/15000006417-getting-started-with-your-yubikey#How_to_backup_your_YubiKey?pgxd4e

      刪除

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。