SCP免密傳輸和SSH登陸流程詳解

SCP免密傳輸和SSH登陸協議詳解

在linux下開發時,常常須要登陸到其餘的設備上,例如虛擬機內ubuntu、樹莓派等等,常常涉及到傳輸文件的操做,傳輸文件有不少中方法,如物理磁盤拷貝,基於網絡的samba服務、SCP傳輸、ftp文件傳輸等等,今天咱們就來聊聊出場頻率最高的SCP傳輸。linux

SCP的使用

在linux環境中,當咱們須要在兩臺機器之間傳輸數據時,常常會用到SCP指令,(SCP指令其實就是基於SCP(secure copy)協議實現的應用程序),SCP的使用示例:git

scp a.out downey@192.168.1.101:/home/donwey

從示例能夠看出,上述示例爲:將a.out這個文件傳送給IP爲192.168.1.101目標機器的/home/downey目錄下,若是是第一次傳輸,終端會顯示:程序員

The authenticity of host '192.168.4.77 (192.168.4.77)' can't be established.ECDSA key fingerprint is 7f:d8:d6:37:4f:a7:6f:8d:a3:00:45:7f:0d:xx:xx:xx.Are you sure you want to continue connecting (yes/no)?

接着鍵入:github

yes

而後系統會提示你輸入帳戶和密碼,注意這個密碼指的是目標機器上用戶的帳號密碼,正確輸入以後傳輸完成。算法

知道怎麼作,固然還須要知道爲何這麼作,因此咱們須要來探究scp指令背後的祕密。ubuntu


預備知識

在介紹SCP協議以前,咱們先得了解一下SSH協議,和計算機中的加密方式,由於SCP協議的登陸過程基於SSH協議。安全

對稱加密

對稱加密,即在數據傳輸過程當中對數據進行加密和解密的算法使用同一個密鑰,這種加密算法有什麼弊端呢?服務器

當客戶端須要與服務器端進行數據傳輸時,無論是由客戶端仍是由服務端產生的密鑰,都得將這個密鑰傳給對方纔能實現加解密,而在傳輸的過程當中就可能形成密鑰的泄漏。網絡

那麼有些人就要說了,那我不用網絡傳輸祕鑰,我可使用口頭傳輸或者u盤拷貝的方法。session

是的,這樣就能夠保證安全,可是在大多數互聯網應用中,通訊雙方是陌生設備,沒法作到上述的方式。

非對稱加密

針對對稱加密帶來的風險,非對稱加密則解決了這個問題。

將加解密使用的密鑰分爲公鑰和私鑰,公鑰能夠公開,而私鑰則由密鑰生成者保存,客戶端使用公鑰進行加密,而服務端用私鑰進行解密,且目前來講尚未出現能從公鑰推算出私鑰的的破解機制。

因此相對於對稱加密而言,這種加密方式更加安全,可是這種加密方式的缺點是會佔用更多的計算機資源,並且這種資源的耗費量是巨大的。

常見的加密方式

對稱加密:

  • DES(Data Encryption Standard):加密速度較快,適合加密大量數據的場合。

  • 3DES:基於DES的加密算法,顧名思義,這是對一塊數據用三個不一樣的密鑰進行三次加密,顯而易見強度更高,更安全。

  • RC2和RC4:用變長密鑰對大量數據進行加密,速度比DES更快

  • IDEA:(International Data Encryption Algorithm)國際數據加密算法,使用 128 位密鑰提供很是強的安全性;

  • AES:高級加密標準,是下一代的加密算法標準,速度快,安全級別高,這個加密算法被普遍應用。

非對稱加密:

  • RSA:是一個支持變長密鑰的公共密鑰算法,須要加密的文件塊的長度也是可變的,目前使用最廣的加密算法

  • Diff ieˉHellman:每次交換數據的時候都使用一組新的密鑰,有效地防止了第三方得到私鑰後解密全部信息,可是同時對中間人攻擊的防禦比較薄弱。


SSH協議

SSH是一種加密的網絡傳輸協議,可在不安全的網絡中爲網絡服務提供安全的傳輸環境,最多見的運用是遠程登陸。SSH的交互流程是這樣的:

  1. 客戶端發送請求:這個請求其實就是ssh登陸請求,即發起者擁有服務器上的某個用戶的帳號密碼,以遠程登陸的方式來操做服務器。

  2. 服務器將公鑰發送給客戶端,這個公鑰是給客戶端進行數據加密用的

  3. 客戶端收到服務器公鑰,肯定是否繼續鏈接?爲何會有這麼一個流程呢,既然我指定了就是要鏈接服務器,爲何還要讓我確認一次,這會不會是畫蛇添足呢?其實否則,這是爲了防範中間人攻擊。

  4. 客戶端用公鑰對密碼進行加密,再發送給服務器

  5. 服務器用私鑰對密碼進行解密,返回登陸結果

中間人攻擊

剛剛提到中間人攻擊,咱們就來看看什麼是中間人攻擊?

咱們大能夠想想,在一個不安全的網絡中,若是我發送的請求被第三方截獲,而第三方把他的公鑰發給我,而我用他的公鑰對密碼進行加密,而後再發送給他,他就得到了完整的帳號密碼,這時候他就能夠拿着從我這兒竊取來的信息登陸服務器。

那麼,在一個不安全的網絡中,咱們該怎樣防範這種攻擊方式呢?通常有兩種方法:

  1. 服務器將公鑰公佈在官方或者以其餘方式公開,讓用戶能夠查到進行對比,若是不匹配,就在第三步的時候取消登陸便可。

  2. CA證書,由一個權威機構CA對公鑰進行認證,CA機構的數字簽名使得攻擊者不能僞造和篡改證書。CA機構會爲申請者發放一個公鑰,CA將該公鑰和申請者的身份信息綁定在一塊兒,併爲之簽字。

    若是一個用戶想鑑別另外一個證書的真僞,他就用 CA 的公鑰對那個證書上的簽字進行驗證,一旦驗證經過,該證書就被認爲是有效的。


SCP的傳輸

說回到SCP的傳輸,SCP的傳輸第一步就是進行SSH的登陸動做,而後再基於SSH協議進行文件的傳輸,整個傳輸過程是加密的。

在上面提到的ssh登陸流程中,是最基本的登陸流程,特色在登陸時服務器要求客戶端提供帳號密碼進行驗證,其實這樣是很是麻煩的,在每次登陸或者傳輸文件時,都要輸入帳號密碼,這對於以偷懶爲終極目標的程序員來講這是不能忍受的。

SCP的免密傳輸

咱們能夠想想,爲何在每次登陸的時候都須要用戶輸入密碼?

全部人都知道這是爲了驗證登陸者的是否有操做權限,那換一個思路想一下,有沒有另一種方法也能驗證登陸者有這個登陸權限呢?

固然是有的,這種驗證方式創建在非對稱加密協議上,當客戶端C想要訪問服務器S時,在客戶端生成一對密鑰(一般使用rsa協議),將客戶端C生成的公鑰放置在服務器S上,這樣在鏈接時只須要驗證服務器S上是否存在客戶端C的公鑰就能夠完成驗證操做。(詳細流程見下文)


實現SCP免密傳輸的操做

  • 若是你在服務器擁有一個帳號,名爲downey

  • 在某一時刻你須要用一臺客戶機A登陸到服務器上進行操做

  • 在客戶機A的家目錄下的.ssh目錄下生成一對祕鑰,linux下的指令爲:

    ssh-keygen -t rsa -P ""
    (ssh-keygen爲祕鑰生成應用程序,-t rsa 表示加密類型爲rsa)

  • 執行上述命令後,系統會提示選擇生成祕鑰放置的目錄和密碼,通常爲默認選擇,一路回車。(可是若是你要追求更高的安全性,你能夠選擇添加上私鑰密碼),而後在/home/downey/.ssh目錄下就會生成兩個文件:id_rsa和id_rsa.pub,其中id_rsa爲私鑰,而id_rsa.pub爲公鑰。

  • 在服務器端的/home/downey/.ssh/目錄下新建文件authorized_keys(若是有則不用建立),將客戶端A上剛剛生成的id_rsa.pub文件中的內容複製到服務器端 /home/downey/.ssh/authorized_keys文件中(若是裏面有內容則另起一行)

這樣就能夠直接用scp指令(或者ssh登陸)進行文件傳輸而不用進行帳號密碼驗證了,至關於客戶機(操做機器)與服務器創建了安全鏈接(原理見下文),若是換一臺機器登陸,依舊須要驗證(由於服務器端的公鑰只與這臺機器上私鑰相匹配)。

注意

在這些文件操做的時候,特別須要注意的就是文件的權限問題,不少朋友就是把文件從其餘地方複製過來,而後修改文件確保文件內容與目標一致就能夠,可是發現這樣的操做並無達到免密傳輸的效果,極可能就是文件權限出了問題

同時,在某些服務器平臺上,可能會提供網頁端的接口來存放客戶端的pub_key,就像github添加公鑰的操做方式,可是原理都是將客戶端公鑰添加到服務器中


免密傳輸的登陸流程

實現SCP傳輸的第一步是通訊雙方進行安全鏈接(登陸),上面提到的SSH登陸流程爲SSH首次登陸的大概講解,咱們不妨來詳細探究在免密傳輸時的登陸流程:

  1. 客戶端向服務端發送鏈接請求,詢問服務器是否支持pubkey的方式進行登陸

  2. 服務端收到客戶端的請求,表示接收pubkey的方式進行登陸。

  3. 接收到服務端的回覆,客戶端決定使用pubkey的方式進行登陸,客戶端將一段數據用私鑰進行加密,生成簽名,而且將本身的公鑰發送給服務器。

  4. 服務端收到客戶端發過來的數據,首先將客戶端的公鑰取出來,在/home/$USER/.ssh/authorized_keys/中查找是否存在客戶端的公鑰,若是有,進行對比。
    僅僅對比是否存在客戶端的公鑰固然是不夠安全的,服務器接着使用客戶端提供的公鑰對客戶端發過來的簽名(經私鑰加密)進行解密,若是解密後的數據內容正確,表示整個驗證流程完成。

  5. 服務端返回登陸結果。


SSH登陸流程疑難解答

客戶端發送給服務器的簽名數據

在上述免密傳輸的登陸部分的第三點我有提到,客戶端將一段數據用私鑰加密生成簽名,而後服務器再對這段數據進行解密,那麼服務器怎麼知道這段數據是否正確呢?

首先,客戶端發送給服務器的數據字段是這樣的:

byte      SSH_MSG_USERAUTH_REQUEST
string    user name
string    service name
string    "publickey"
boolean   TRUE
string    public key algorithm name
string    public key to be used for authentication  
string    signature     //數據簽名部分

而客戶端使用私鑰進行加密的數據字段是這樣的:

string    session identifier
byte      SSH_MSG_USERAUTH_REQUEST
string    user name
string    service name
string    "publickey"
boolean   TRUE
string    public key algorithm name
string    public key to be used for authentication

對比發現,事實上客戶端同時發了一份數據和數據的簽名給服務端,服務端就能夠作對比了。


爲何公鑰能夠對私鑰加密的數據解密

不少朋友看完上述免密傳輸登陸流程以後,表示很是疑惑:

爲何公鑰能夠對私鑰加密的數據進行解密?
公鑰原本就是公開的,那豈不是私鑰加密的數據根本沒有安全性可言?

首先回答第一個問題:爲何公鑰能夠對私鑰的加密數據進行解密。答案是:這是SSH協議的規定(好像是廢話)。

好吧,正經地回答第二個問題,公鑰是公開的,全部人均可以得到,而私鑰只有擁有者纔有,那由這對密鑰加密的數據是否就沒有安全性可言呢?

答案固然不是,安全性高着呢。只是,通常的加密過程是公鑰加密,私鑰解密,這部分數據天然是安全的。

那麼私鑰加密的數據呢,私鑰加密的數據確實沒有安全性可言,由於用私鑰加密數據根本就不是爲了安全性,而是做爲一種驗證身份的手段。
由於私鑰是惟一的,一旦使用公鑰對私鑰加密的數據解密成功,服務端S就能夠徹底肯定這條消息是由擁有對應私鑰的客戶端C發出的,而不是第三方假裝者發出的。

因此,公鑰加密私鑰解密,是爲了數據的安全性,而私鑰加密公鑰解密,則是爲了驗證數據發送者的身份。


數據傳輸的加密方式

通常狀況下SSH使用rsa加密算法登陸,SCP基於SSH協議,因此不少人天然地認爲在數據傳輸時,使用的加密算法也是rsa。

事實上,因爲非對稱加密算法計算太過於耗時,對全部數據進行加密根本不現實,因此在傳輸數據時通常使用對稱加密算法。

上面有提到,對稱加密算法的弊端是密鑰傳輸過程容易被竊取,因此一般使用非對稱加密算法來傳輸對稱加密算法的密鑰,來保證安全性。

爲此,我還使用wareshark工具試圖梳理整個數據傳輸流程,花了一天的時間得出一個結論:針對整個SCP實現的加密算法這一塊,以博主的水平,暫時惹不起....(不過也只是暫時!!)

不過收穫仍是有的:SCP數據傳輸流程結合了多種加密算法,同時還根據不一樣級別的安全要求結合不一樣的加密算法。

通常來講,綜合對稱和非對稱加密算法的特性,非對稱加密通常用於登陸驗證、密鑰傳輸等數據量小、安全性要求較高的的部分。

而對稱算法用來傳輸大量數據。


網上的錯誤描述

事實上,網絡上對於SSH的登陸過程描述有很多錯誤之處,最經典的一個錯誤觀點是服務器發送一個經過公鑰加密的字符串給客戶端,客戶端私鑰進行解密,而後發給服務端。

服務端將發出的字符串與收到的字符串進行對於,完成驗證過程。

這種作法看起來是很是合理的,但事實上SSH並不採用這種作法,具體緣由引用官方文檔中的一句話:

the signing operation involves some expensive computation.  
To avoid unnecessary processing and user interaction。

這句話意思很簡單,加密的計算操做是很是耗時的,咱們應該避免沒必要要的交互以節省資源。

爲何我那麼自信肯定它們的描述有誤呢?並非飄柔給個人自信,而是官方文檔

(多嘴一句,找資源必定要先找官方文檔的)


github的免密傳輸

用過github的盆友可能對免密傳輸有種熟悉的感受,沒錯!在github的配置中,若是須要進行免密傳輸,流程是:

  1. 在客戶機生成一對祕鑰,一樣是id_rsa,id_rsa.pub

  2. 將id_rsa.pub裏的內容添加到github的settings的SSH and GPG keys選項頁面中

一樣的,至關於github服務端與機器已經創建用戶識別機制,不須要再用帳號密碼來識別。


好了,關於SCP傳輸的討論就到此爲止啦,若是朋友們對於這個有什麼疑問或者發現有文章中有什麼錯誤,歡迎留言

原創博客,轉載請註明出處!

相關文章
相關標籤/搜索