一、對稱加密與非對稱加密 對稱加密: 加密和解密的秘鑰使用的是同一個. 非對稱加密: 非對稱加密演算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰;簡稱公鑰和私鑰對稱加密 對稱加密的密碼強度高、較難破解。但是秘鑰的保存成為了一個重要的問題,特別是如果機群龐大的時候,一旦某個客戶端暴露了秘鑰, ...
一、對稱加密與非對稱加密
對稱加密: 加密和解密的秘鑰使用的是同一個.
非對稱加密: 非對稱加密演算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰;簡稱公鑰和私鑰
對稱加密
對稱加密的密碼強度高、較難破解。但是秘鑰的保存成為了一個重要的問題,特別是如果機群龐大的時候,一旦某個客戶端暴露了秘鑰,會給整個系統帶來嚴重的安全問題
非對稱加密
公鑰加密後的密文,只能通過對應的私鑰進行解密。而通過公鑰推理出私鑰的可能性微乎其微。私鑰是Server端獨有,而且私鑰並不會在網路中進行傳輸,這一定程度上保證了數據的安全性,充分利用了非對稱加密的特性
非對稱加密的過程:
① 客戶端向伺服器發送請求,並得到伺服器傳來的公鑰
②-④ 客戶端利用從伺服器得到公鑰對登錄數據(用戶名和密碼或其他驗證數據)進行加密;然後將加密後的數據傳給伺服器
⑤-⑦ 伺服器利用私鑰將從客戶端收到的數據進行解密。並將解密後的數據與正確數據(資料庫中存儲的用戶名和密碼或其他)進行校驗,根據得到校驗結果允許或拒絕此次登錄請求;並將最後結果通知客戶端
二、非對稱加密的安全性問題
從上面的分析中,我們得知了非對稱加密確實解決了一定的安全問題,那麼它就一定安全了嗎?答案是絕對否定的。因為通過上面的分析,我們得知客戶端對於伺服器方是沒有認證的。而這時如果一個假冒的伺服器方將自己的公鑰發給了客戶端,它可以很簡單的把客戶端的加密數據進行解密,因為公鑰和私鑰都是它自己的啊。這樣客戶端的數據就被竊取了。這種攻擊方式叫做中間人攻擊。其原理如下:
三、SSH原理
因為非對稱加密體質非常耗費系統資源,因此SSH僅將非對稱加密用於登錄連接過程,而連接後的數據交互採用了對稱加密。我們通過上面得知,即使是非對稱加密也存在一個問題——如何解決中間人攻擊?
https中針對中間人攻擊採取了公證機制——通過CA來進行公證,可是SSH的公鑰和私鑰都是自己生成的,沒法公證。只能通過Client端自己對公鑰進行確認。
因此,SSH引入了known_hosts文件。客戶端的每次連接請求,伺服器都會將相關信息與known_hosts文件中的信息進行匹配,如果是第一次連接,伺服器會將相關信息存儲在known_hosts文件中,在這個過程中,伺服器會請求客戶端的用戶進行確認;拿什麼確認呢?公鑰指紋!什麼是公鑰指紋?
因為公鑰很長,長達1024位甚至2048位或更長,如果比較這麼長的數據會很耗費系統資源。所以這裡的公鑰指紋是指利用MD5演算法對公鑰進行加密後形成的128位的一個數據;客戶端利用這個從伺服器獲取到的公鑰加密後的公鑰指紋和真正伺服器的公鑰(需提前獲取)加密後的公鑰指紋進行比較,如果一致的話,用戶需要輸入yes確認此次認證,如果不一致的話,有可能遭到了中間人攻擊,用戶需要輸入no對此次認證進行中斷,防止數據泄露。如圖:
如果不是第一次連接,客戶端(登錄方)會將自己的known_hosts文件中的公鑰指紋與伺服器傳來的公鑰指紋進行對比,如果一致,連接會繼續,客戶端輸入用戶名和密碼直接登錄就可以。如果不一致,客戶端會判定此次連接遭到了中間人攻擊,並阻止此次連接,如圖:
如果是用戶主動重新部署了SSH伺服器,並且確認此次連接無誤的話,用戶需要在客戶端(登錄方)的known_hosts文件中刪除與該地址對應的公鑰數據,重新進行SSH連接認證即可
四、SSH免密登錄原理
基於口令的認證方式每次登錄都需要輸入密碼,這是比較麻煩的一件事情,為此,SSH引入了基於公鑰認證的登錄方式,這也是SSH免密登錄的依據,那麼基於公鑰認證的登錄方式具體步驟是怎樣的呢?
1.登錄端A生成公鑰和私鑰,並(手動)將公鑰追加到被登錄端B的 authorized_key 文件中
2.登錄端A向被登錄端B發送連接請求,並將公鑰發送給被登錄端B
3.被登錄端B接受登錄端A發來的公鑰,並將該公鑰與自己的 authorized_key 文件中的所有存儲的公鑰進行比較,如果並未發現有此公鑰存在,則登錄端A需要進行口令認證與被登錄端B進行連接。如果在 authorized_key 文件中找到了與登錄端A發送的公鑰相同的公鑰,則生成隨機數R,並利用公鑰加密該隨機數得到 publickey(R),最後被登錄端B將 publickey(R) 傳給登錄端A
4.登錄端A利用私鑰對 publickey(R) 進行解密得到R,登錄端A和被登錄端B通信時會產生一個會話ID(sessionKey)。登錄端A利用MD5演算法將R和ID進行加密,並將加密後的數據傳給被登錄端B
5.被登錄端B也利用MD5演算法對R(被登錄端B在第3步中隨機生成的)和會話ID(二者的會話屬於同一會話,因此會話ID sessionKey是相同的)進行加密。並將加密後的數據與第四步登錄端傳來的加密數據進行比較,如果相同,則允許此次登錄端A的連接請求,並與之建立連接。如果不同,則二者繼續進行基於口令認證的連接請求
註意:
免密登錄的任何一個環節出現不匹配時,登錄端A和被登錄端B的連接將會被轉換為基於口令的認證連接
五、用生活實例來演示免密登錄
老闆Boss在伺服器B上創建了一個userb用戶,可是他回到家後想用客戶機A使用userb用戶連接伺服器B
首先,老闆在自己辦公室的客戶機A上創建了秘鑰,包括公鑰和私鑰。老闆把公鑰傳到公司的伺服器S上;可是這個老闆不可能把公司的所有事情都包了,那樣太累了,於是他在公司的伺服器S上做了一個允許訪問該伺服器的 "電腦編號-各級部門經理賬號" 認證列表,該認證列表中包含了公司的所有部門經理的辦公電腦的MAC地址和其對應的不同級別的用戶賬號。只有被該列表包含的 "電腦編號-各級部門經理賬號" 才有資格免密登錄此伺服器進行辦公
有一天老闆想要統計公司今年的盈虧狀況,所以要查看公司的賬單,老闆在客戶機A上使用SBoss登錄伺服器S;當伺服器S收到老闆的連接請求後,伺服器B上的 "電腦編號-各級部門經理賬號" 會判斷自己裡邊是否有與客戶機A通過SBoss登錄伺服器的認證,如果沒有的話,老闆還得輸入SBoss在伺服器B上的密碼進行登錄;如果有的話,伺服器B會發送一個用客戶機A上的公鑰加密的隨機數給客戶機A,客戶機A用私鑰解密這個隨機數,並用MD5演算法對該隨機數和當前會話ID組合的數據進行加密,然後將加密後的數據發送給伺服器S,伺服器S也利用MD5演算法對該隨機數和當前會話ID進行加密,並與客戶機A傳來的加密數據進行對比。根據對比結果決定是否允許此次免密登錄請求
上文中的抽象事物與ssh相關文件對應關係如下:
老闆 ===> 操作電腦用戶的相關管理人員
伺服器S ===> SSH服務端
客戶端A ===> SSH客戶端
SBoss ===> SSH服務端管理員賬號
公鑰 ===> SSH客戶端的 id_rsa.pub 文件
私鑰 ===> SSH客戶端號的 id_rsa 文件
"電腦編號-各級部門經理賬號" ===> SSH服務端的 authorized_keys 文件
六、SSH免密登錄實戰
單向免密登錄方法一
1.客戶端A執行以下命令,生成秘鑰
ssh-keygen -t rsa
註意:一路回車即可
2.客戶端A執行以下命令,將公鑰傳給服務端B
ssh-copy-id [伺服器B的IP地址]
3.客戶端A執行以下命令(註意:先不要執行它,若B出現登錄不了A的狀況再執行)
ssh-add id_rsa
4.伺服器A執行以下命令驗證
ssh [服務端B IP地址]
或
ssh [服務端B上的用戶名]@[服務端B IP地址]
5.如果出錯的話,可能是以下幾種原因
1.兩台機器均設置相應的免密登錄
2.
chmod 700 /home/[用戶名]/.ssh/
chmod 600 /home/[用戶名]/.ssh/authorized_keys
3.修改/etc/ssh/ssh_config配置文件如下關鍵字
GSSAPIAuthentication no
單向免密登錄方法二
1.客戶端A生成公鑰和秘鑰
ssh-keygen -t rsa
註意:
一路回車即可
2.客戶端A將公鑰傳給服務端B
scp id_rsa.pub [email protected]:~/.ssh/
3.服務端B將A的公鑰追加到自己的 authorized_keys 文件中(如果沒有該文件,則先新建再追加)
touch authorized_keys
cat id_rsa.pub >> authorized_keys
4.客戶端A執行以下命令(註意:先不要執行它,若B出現登錄不了A的狀況再執行)
ssh-add id_rsa
5.客戶端A登錄服務端B
ssh [email protected]
雙向免密登錄
1..編輯主機A和主機B的sshd配置文件 vim /etc/ssh/ssh_config
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
2.重啟 sshd 服務
service sshd restart
3.主機A新建用戶usea,主機B新建用戶userb
主機A的操作:
useradd usera
passwd usera
主機B的操作:
useradd userb
passwd userb
4.主機A使用usera用戶登錄,創建ssh秘鑰
su usera
ssh-keygen -t rsa (一直回車)
5.主機B使用userb用戶登錄,創建ssh秘鑰
su userb
ssh-keygen -t rsa (一直回車)
6.主機A使用usera在 ~/.ssh/ 目錄下新建authorized_keys文件,並且將usera和userb的公鑰(id_rsa.pub)複製到該文件中
cd ~/.ssh/
touch authorized_keys
將主機A的usera公鑰複製進主機A的usera的目錄下的 authorized_keys 文件
cat id_rsa.pub > authorized_keys
將主機B的userb公鑰追加到主機A的usera的目錄下的 authorized_keys 文件
ssh userb@[主機B的IP地址] cat /home/userb/.ssh/id_rsa.pub >> authorized_keys
7.主機A使用usera用戶執行以下命令
chmod 700 /home/usera/.ssh/
chmod 600 /home/usera/.ssh/authorized_keys
8.將主機A的用戶usera的~/.ssh目錄下的兩個配置文件 authorized_keys、known_hosts 複製到主機B的userb用戶的~/.ssh目錄下
scp authorized_keys known_hosts userb@[主機B的IP地址]:~/.ssh/
9.主機B使用userb用戶設置指定文件許可權
chmod 700 /home/userb/.ssh/
chmod 600 /home/userb/.ssh/authorized_keys
10.到此,主機A和B就可以通過usera和userb通過ssh免密登錄了
ssh userb@[主機B的IP地址]
ssh usera@[主機A的IP地址]