圖解SSH原理及兩種登錄方法

SSH(Secure Shell)是一套協議標準,可以用來實現兩臺機器之間的安全登錄以及安全的數據傳送,其保證數據安全的原理是非對稱加密

傳統的對稱加密使用的是一套祕鑰,數據的加密以及解密用的都是這一套祕鑰,可想而知所有的客戶端以及服務端都需要保存這套祕鑰,泄露的風險很高,而一旦祕鑰便泄露便保證不了數據安全。

非對稱加密解決的就是這個問題,它包含兩套祕鑰 - 公鑰以及私鑰,其中公鑰用來加密,私鑰用來解密,並且通過公鑰計算不出私鑰,因此私鑰謹慎保存在服務端,而公鑰可以隨便傳遞,即使泄露也無風險。

保證SSH安全性的方法,簡單來說就是客戶端和服務端各自生成一套私鑰和公鑰,並且互相交換公鑰,這樣每一條發出的數據都可以用對方的公鑰來加密,對方收到後再用自己的私鑰來解密。

鏈接創建

由上一張圖可以看出來,兩臺機器除了各自的一套公、私鑰之外,還保存了對方的公鑰,因此必然存在一個交換各自公鑰的步驟。實際上並不是簡單的各自發送公鑰,而是存在一些專門的算法。這一步在首次鏈接時、數據傳送之前發生。

  1. 客戶端發起鏈接請求
  2. 服務端返回自己的公鑰,以及一個會話ID(這一步客戶端得到服務端公鑰)
  3. 客戶端生成密鑰對
  4. 客戶端用自己的公鑰異或會話ID,計算出一個值,並用服務端的公鑰加密
  5. 客戶端發送加密後的值到服務端,服務端用私鑰解密
  6. 服務端用解密後的值異或會話ID,計算出客戶端的公鑰(這一步服務端得到客戶端公鑰)
  7. 至此,雙方各自持有三個祕鑰,分別爲自己的一對公、私鑰,以及對方的公鑰,之後的所有通訊都會被加密

這裏有一個有趣的地方,兩臺機器第一次使用SSH鏈接時,當服務端返回自己的公鑰(第2步)的時候,客戶端會有一條信息提示,大意是無法驗證對方是否可信,並給出對方公鑰的MD5編碼值,問是否確定要建立鏈接。

這是因爲SSH雖然傳輸過程中很安全,但是在首次建立鏈接時並沒有辦法知道發來的公鑰是否真的來自自己請求的服務器,如果有人在客戶端請求服務器後攔截了請求,並返回自己的公鑰冒充服務器,這時候如果鏈接建立,那麼所有的數據就都能被攻擊者用自己的私鑰解密了。這也就是所謂的中間人攻擊

利用密碼登錄

SSH還常用來遠程登錄到別的機器,有兩種常用的方法,第一種便是賬號密碼登錄。

  1. 服務端收到登錄請求後,首先互換祕鑰,詳細步驟如上一節所述。
  2. 客戶端用服務端的公鑰加密賬號密碼併發送
  3. 服務端用自己的祕鑰解密後得到賬號密碼,然後進行驗證
  4. 服務端用客戶端的公鑰加密驗證結果並返回
  5. 服務端用自己的祕鑰解密後得到驗證結果

利用公鑰登錄

有些時候並不是開發者手動去連接服務器,而是客戶端的程序需要連接到服務器,這時候用密碼登錄就比較不方便,一是需要處理輸入密碼的問題,二是需要想辦法安全的儲存密碼到程序裏,這種情況下便可以利用公鑰來進行無密碼登錄。

  1. 客戶端用戶必須手動地將自己的公鑰添加到服務器一個名叫authorized_keys的文件裏,顧名思義,這個文件保存了所有可以遠程登錄的機器的公鑰。
  2. 客戶端發起登錄請求,並且發送一個自己公鑰的指紋(具有唯一性,但不是公鑰)
  3. 服務端根據指紋檢測此公鑰是否保存在authorized_keys中
  4. 若存在,服務端便生成一段隨機字符串,然後利用客戶端公鑰加密並返回
  5. 客戶端收到後用自己的私鑰解密,再利用服務端公鑰加密後發回
  6. 服務端收到後用自己的私鑰解密,如果爲同一字符串,則驗證通過

利用公鑰登錄的關鍵是必須手動將客戶端的公鑰添加到服務端,比如GitHub便有這一步驟,添加了之後便可無密碼登錄。


參考文獻:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章