SSH 金鑰詳解

SSH 金鑰驗證是一種無需密碼登入伺服器的方式:你的電腦不再輸入一個伺服器可以核對的祕密,而是對伺服器發來的挑戰進行簽章,伺服器再用它已存檔的公鑰驗證簽章。私鑰從不經過網路,因此無物可截獲、無物可釣取、無物可猜測。本文講解金鑰對的兩半如何運作、2026 年該選擇哪種金鑰類型、指紋如何在首次連線時擋住中間人、如何保持 authorized_keys 與 known_hosts 整潔,以及金鑰外洩時具體該做什麼。要在瀏覽器中產生、檢查或轉換金鑰,請使用SSH 金鑰套件;要檢查你仍在用的密碼,請使用密碼外洩檢查。

什麼是 SSH 金鑰驗證

每一次登入都是伺服器提出的一個問題——你真的是你聲稱的那個人嗎?——而密碼的回答方式是把祕密本身交出去。這正是整個安排的弱點:祕密會流動、會被竊聽、會被重播、會被一次次猜測,直到被攻破。SSH 金鑰驗證改變了回答方式。你的電腦不再傳送祕密,而是用一個從不離開本機的私鑰對伺服器發來的隨機挑戰簽章,伺服器再用 authorized_keys 檔案中儲存的公鑰核對簽章。因為挑戰是隨機的,證明每次都是全新的;祕密從不出現於網路上,竊聽者學不到任何可以重用的東西;而且根本沒有密碼可猜,因為整個過程完全不涉及密碼。

這個想法比現代網際網路還要古老——公鑰密碼學可以追溯到 20 世紀 70 年代——但 SSH 讓它成為連線伺服器的日常方式,此後協定一直沿用至今。當你執行 ssh user@server 時,用戶端與伺服器先建立工作階段,伺服器針對你的帳戶發出挑戰,你的 SSH 代理用私鑰簽章——通常是你先用密碼解鎖金鑰之後。如果簽章驗證通過,你就進去了。整個交換不依賴伺服器也知道的共享祕密,這就是為什麼伺服器被攻破也不會暴露你的憑證:伺服器手裡只有公鑰,而公鑰對登入毫無用處。這種不對稱——伺服器能驗證卻不能冒充——就是金鑰的全部安全論據,也是為什麼失去私鑰一半的控制是唯一真正要命的失敗。

公鑰與私鑰

金鑰對的兩半遵循相反的規則,而大多數 SSH 錯誤都來自把它們當成一回事。公鑰就是用來到處複製的:貼進你使用的每一台伺服器的 authorized_keys、Git 託管帳戶、任何接受 SSH 金鑰的服務。它可以發表在公開儲存庫裡、印在投影片上、寄電子郵件給管理員,因為它能讓別人做的只有驗證簽章。知道你的公鑰不會給攻擊者任何登入的手段,就像知道你的門牌號碼並不會給別人你家大門的鑰匙一樣。公鑰這一半是鎖,而不是鑰匙,而鎖本來就是給人看的。

私鑰就是鑰匙本身,它的規則恰恰相反:它從不離開你的電腦,只有你能讀取,絕不能貼進聊天、工單、電子郵件、論壇貼文或共享文件——哪怕是問它是否安全。持有它的人就能以你的身分登入每一台信任對應公鑰的伺服器,中間沒有任何密碼提示,也沒有任何第二因素——除非你自己設定過。在磁碟上它住在 ~/.ssh 裡,靠檔案權限保護——chmod 600,只有擁有者可讀寫——理想情況下還要有密碼保護,密碼會加密檔案,讓被盜的副本在沒有解鎖密碼的情況下依然無用。密碼不是金鑰的一部分;它是裝著鑰匙的盒子上的掛鎖。盒子丟了,掛鎖就是小偷與你的伺服器之間唯一的屏障,這就是為什麼沒有密碼的私鑰絕不應該離開一台你完全掌控的機器。

Ed25519 與 ECDSA、RSA:2026 年該選哪一個

2026 年的預設答案是 Ed25519,這也是本站產生的預設類型。Ed25519 是 256 位元的橢圓曲線金鑰:不到一秒就能產生,簽章很快,公鑰只有短短一行。自 2014 年起 OpenSSH 就支援它,所有目前的伺服器與用戶端也都支援,它的安全性建立在一條公開設計、沒有可疑常數的曲線上。除非你的環境迫使你另作選擇,否則新金鑰沒有實際理由選別的。如果你只從本文帶走一條建議,就是這一條:產生 Ed25519,設定密碼,然後繼續做事。

其他類型是為例外情況準備的。當政策要求 NIST 曲線時——某些受監管環境與較舊的硬體權杖有此規定——ECDSA 的 NIST P-256 或 P-384 曲線是正確選擇;如果某個瀏覽器或裝置無法產生 Ed25519,它也是可靠的替代。RSA 仍然是通用兜底:RSA 2048 是值得使用的下限,RSA 3072 或 4096 適用於對方完全無法使用橢圓曲線的情況,如今這主要指非常舊的系統和少數嵌入式裝置。低於 RSA 2048 的任何金鑰——RSA 1024、DSA、ssh-dss——都屬於舊遺產,應當退役:SSH 金鑰套件正是因此把它們標記為弱金鑰。不過金鑰長度不是全部:複製到你已不再擁有的筆記型電腦上的 4096 位元 RSA 金鑰,比保管得當的 256 位元 Ed25519 金鑰更糟糕,因為 SSH 金鑰的失敗模式幾乎從來不是數學,而是檔案。

指紋與首次連線

第一次連線伺服器時,SSH 會顯示一串看起來隨機的字元,並問你是否信任它:256 SHA256:M8zvXkwyrGfPUmaHSSdA1aFQkH8AVSRycOxaZHru7dQ。這串字元是伺服器主機金鑰的指紋——伺服器公鑰的雜湊——也是你與中間人之間唯一的屏障。如果指紋與管理員公布的、或你透過其他管道核實過的一致,那麼回答你的機器就確實是你想連線的伺服器。如果不一致,就停下:可能有人在攔截連線,也可能伺服器重建後換了新金鑰,無論哪種情況,安全的做法都是先核實再輸入 yes。這個提示是 SSH 在做它最重要的工作,而出問題的人正是那些訓練自己不看提示就輸入 yes 的人。

你可以在連線之前就用 ssh-keygen -lf 核實指紋,它為每個金鑰印出一行:位元數、指紋、註解和方括號中的金鑰類型,例如 256 SHA256:… [email protected] (ED25519)。SSH 金鑰套件印出指紋的格式與它完全一致,因此你在瀏覽器裡看到的值可以與伺服器顯示的值逐字比對。一旦你接受了某個主機金鑰,SSH 會把它保存在 ~/.ssh/known_hosts 中,如果它將來發生變化,就會大聲警告你——甚至拒絕連線。這個警告不是用某個參數繞過去的麻煩;它是正在響起的警報。唯一常規的例外是伺服器確實重建過,這時管理員應當事先公布新指紋,而你應當在重新連線之前用 ssh-keygen -R hostname 刪除舊項目。

authorized_keys 的日常維護與 known_hosts

伺服器 authorized_keys 檔案中的每一行都是一扇門,而這些門會在需要它的人離開很久之後依然開著。外包人員的筆記型電腦、持續整合任務、在已被抹除的機器上產生的金鑰、兩年前換了團隊的同事——每一行都仍然有效,每一行都是你不再盯著的憑證。稽核很簡單,每隔幾個月做一次就值得:複製檔案,貼進 SSH 金鑰套件的「檢查」分頁,看看傳回的結果。重複項目——同一個公鑰出現兩次——意味著有人沒有檢查就又貼了一次,應當合併為一行。弱項目——低於 2048 的 RSA、DSA、ssh-dss——應當刪除並替換。而任何註解中提到的人、機器或用途你已經認不出來的行,都應當當作一扇要關上的門,直到它的主人來認領。

known_hosts 也值得從另一面得到同樣的關注。它記錄著你連線過的每一台伺服器的主機金鑰,SSH 會對照它檢查每一次新的連線。有些項目是經過雜湊處理的——|1| 後面跟著 base64——這會隱藏主機名稱,是為可能遺失或被檢查的筆記型電腦準備的隱私功能;SSH 金鑰套件會把這些項目報告為已雜湊,而不是假裝它們可讀,因為已雜湊的項目無法對照公布的指紋核實,只能當作已經被接受來信任。這個檔案本身也是證據:滿是早已不用的伺服器的 known_hosts,就是你的憑證去過哪裡的地圖,而清理它不花任何代價。這兩個檔案合在一起,就是你的 SSH 信任在兩個方向上的完整紀錄——誰可以以你的身分登入,以及你信任哪些機器就是它們自己——而如果沒人去看,它們都會悄悄腐爛。

金鑰外洩時該怎麼辦——以及密碼說明

外洩的金鑰不是先調查、後行動的謎題;它是要換掉的金鑰,操作順序很短。產生一對新金鑰。從每一台伺服器和每一個服務的 authorized_keys 中刪除舊公鑰——你的伺服器、Git 託管、部署流水線,凡是安裝過這把金鑰的地方。然後檢查舊金鑰能觸及什麼,看看有沒有異常:你沒有新增過的 authorized_keys 新行、你沒有工作的時間段裡的登入、不熟悉的程序。如果發現任何異常,就把它當作一次入侵來對待,而不是虛驚一場,再從那裡展開調查。千萬不要做的事,是從自己的筆記型電腦上刪除舊私鑰就以為大功告成:刪除你自己的副本對已經外洩的副本毫無作用,而仍然躺在 authorized_keys 裡的公鑰依然是一扇能正常開啟的門。

密碼不會改變這份清單,但它會改變你執行清單的緊迫程度。外洩為檔案的受密碼保護的金鑰仍然是個問題——攻擊者可以離線、以機器速度猜測密碼——但一個強密碼能為你爭取到在猜測成功之前完成輪換的時間。未加密的金鑰則完全爭取不到時間,這就是為什麼本站對產生器產出的東西直言不諱:第 1 版產生的是未加密金鑰,沒有密碼選項,因為 OpenSSH 加密私鑰的 bcrypt KDF 屬於第 2 版的範圍。如果你在此產生金鑰,請用 chmod 600 保護檔案,並在自己的電腦上用 ssh-keygen -p 新增密碼——只需要十秒鐘,原地轉換檔案,而且是整篇文章中價值最高的習慣。產生金鑰,設定密碼,只安裝公開的那一半,每年稽核兩次檔案,信任之前核實每一個指紋:這就是全部的紀律,寫在一張索引卡上都綽綽有餘。

來源與延伸閱讀

常見問題

2026 年我該用哪種 SSH 金鑰類型?

幾乎所有情況都用 Ed25519:256 位元,速度快,體積小,所有目前的伺服器與用戶端都支援。只有當政策要求 NIST 曲線時才用 ECDSA P-256,只有當對方無法使用橢圓曲線時才用 RSA 3072 或 4096。低於 RSA 2048 的一律退役。

我怎麼知道自己連線的是正確的伺服器?

首次連線時,把 SSH 顯示的主機金鑰指紋與管理員公布的指紋比對,用 ssh-keygen -lf 或 SSH 金鑰套件——兩者印出指紋的格式相同。如果一致就接受;SSH 會把它保存在 known_hosts 中,一旦變化就會警告你。如果不一致,先停下核實,不要急著輸入 yes。

我的私鑰外洩了,我先做什麼?

產生一對新金鑰,然後從每一台伺服器與服務的 authorized_keys 中刪除舊公鑰——Git 託管與部署流水線也包括在內。只刪除自己手裡的私鑰副本是不夠的,因為外洩出去的副本在公鑰被刪除之前仍然有效。然後檢查舊金鑰能觸及的地方有沒有被使用的跡象。