看到本論壇上時常有人問 GPG error 的問題,網路上的相關資源也大多是一兩行指令帶過,使很多新手即使問題解決了也仍然似懂非懂地,在此特地把我很久以前發表在摩托學員的文章轉過來這裡,希望對大家會有所幫助:
一、前言:
在
開放原始碼軟體的世界裡,任何人都可輕易取得軟體的原始程式碼並自行修改、編譯、散播,尤其是像 Ubuntu 與 Debian
這類可以經由幾個簡單的按鈕、指令驅動龐大而複雜的 APT
系統進行全作業系統的套件升級、管理機制,安全性考量是一個非常重要的課題,因為沒有人希望下載回來安裝的軟體,是被有心人士惡意篡改且穿插了惡意程式碼
片段在其中。因此,在 Debian 和 Ubuntu 的 APT 系統中,引進了所謂的非對稱式金鑰加密、解密法以及 MD5 hash
演算法機制來增加其安全性,以確保從網路下載回來的軟體套件是可信任的。
二、數位簽章簡介:
簡而言之,文件發佈者會有一組相對應
的金鑰(key),分別為公開金鑰(public key)以及私密金鑰(private
key),公開金鑰顧名思義就是要公開散播給大家取得的,他是一大串體積大約 2k
左右的長碼,而私密金鑰則是只有文件發佈者才有的秘密鑰匙。發佈者每當要發佈時將原始文件(明文,plain
text)以私密金鑰加密演算後變成密文(cipher
text)再行傳送,接收方則可使用發佈者的公開金鑰對該文件進行解密演算方可得原始明文。在這過程中,如果使用於加密的私密金鑰或者用來解密的公開金鑰
並非正確的話,接收端都無法正確的還原出原始文件,因此可以達到資料來源可信任的目的。
然而,這個機制並非堅不可破,要從公開金鑰去反向推倒演算
出私密金鑰是可行的,只是其所需的運算量非常龐大,可能需要超級電腦才有辦法在幾年內破解出,普通的個人電腦要解出可能運算到電腦變成古董了都還沒破解出
來。因此,為了安全考量,通常金鑰組都會每過一段時間要淘汰掉重新產生一組新的來使用,這也是為什麼 APT
系統中時常都必須重新下載新的公開金鑰的緣故。
三、MD5 簡介:
這是一個單向的雜湊(hash)演算法則,可以輸入任意長度的
資料,然後產生一串 128
位元的碼串,隨著輸入資料的內容、長度不同,所產生的碼串都會不一樣,而由所產生的碼串則非常難以還原回原始資料。因此只要原發佈者將該文件以 MD5
演算過後產生的 128 位元碼串公佈出來,接收端即可將收到的文件先以 MD5
演算後所產生的碼串來跟原發佈者的碼串進行比對,若兩者相同則表示文件內容確定為原發佈者的文件,兩者內容一致未被篡改。
四、APT 系統中的數位簽章機制:
由
於使用金鑰加密、解密時,其流程中的密文體積以及演算過程的時間會隨著明文的體積成正比成長,因此在 APT
系統中將整個軟體套件進行金鑰加密、解密則顯的太過不切實際。所以在 APT 系統中軟體套件或原始碼本身都是以明文的方式存放於伺服器上並提供所有的
APT 的 Client 程式下載,套件維護者只會對軟體套件先進行 MD5 演算產生 128 位元的碼串,再針對該碼串進行金鑰加密。
接收
端在進行套件清單更新時(apt-get update)會下載所有 deb 套件的 MD5 碼串以及其加密後的密文,此時 APT Client
則必須擁有該套件發佈者的公開金鑰才有辦法正確的將接收到的密文還原成 MD5 的碼串,還原出該碼串後即可跟下載回來的碼串進行比對以確定該 MD5
碼串是可靠的,之後再對所有下載回來要安裝的軟體套件進行一次 MD5 演算以產生一個新的碼串,並將新碼串拿來跟可靠的 MD5
碼串比對,藉以確認軟體套件本身是未被篡改的。
六、實際操作:
在 APT 中管理金鑰:
以 root 身份使用以下指令可察看目前系統中的 APT 所持有公開金鑰列表:
apt-key list
指令會產生很多行含有 xxxxx/xxxxxxxx 格式的資料,斜線前的那串碼是金鑰擁有者的 ID,斜線之後的八碼是金鑰指紋的末八碼。
由於公開金鑰是要公佈給大家任意取得的,因此一般而言都會有所謂的鑰匙伺服器(key server),上面專門存放大量的公開金鑰供取用,取用的方式就是指定該鑰匙的指紋(finger print),通常是該金鑰的最末 16 碼(或末八碼)。
當
系統在進行套件清單更新時出現了類似 NO_PUBKEY xxxxxxxxxxxxxxxx 的錯誤訊息時,則表示有公開金鑰已過期或者是有新加入
apt 的 source 但未下載該對應之公開金鑰,而後面那串碼就是新的公開金鑰之指紋,只要使用以下指令即可從 key server
下載到該金鑰:
gpg --keyserver hkp://wwwkeys.eu.pgp.net --recv-keys xxxxxxxxxxxxxxxx
gpg 是一套專門管理金鑰的系統,但是他和 APT 的金鑰管理系統是獨立開來的,因此下載到金鑰後還必須將他匯給 APT 才行,指令如下:
gpg --armor --export xxxxxxxxxxxxxxxx | apt-key add -
之後在使用 APT 的金鑰列表指令應該就可看到新的公開金鑰了。
對
於不想要使用指令的人來說,在 Synaptic 軟體裡也可以用滑鼠點點來完成這個任務,首先就是要把你要加入的金鑰檔案下載下來,通常是一個
.gpg 為副檔名的的純文字檔,裏面就含有完整的公開金鑰。然後在 Synaptic
裡的「設定」->「套件庫」->「認證」->「匯入金鑰檔案」把該金鑰檔匯進去之後,就大功告成嚕!