SSH(SecureShell),是建立在應用層基礎上的安全協議,其SSH客戶端適用於多種平台,可以有效防止遠程管理過程中的信息泄露問題。
1.SSH發展歷史
-
SSH1.x
SSH是1995年由芬蘭赫爾辛基大學研究員Tatu Ylönen提出用於替代Telnet等非安全協議的遠程Shell協議。SSH1.x通過CRC-32避免數據被篡改,后來逐步演化為私有軟件。
-
SSH2.x
由IETF工作小組發布SSH-2標准。采用MD5和SHA-1實現通信的完整性,安全性優於SSH-1。
-
OpenSSH
目前最流行的SSH實現的開源版本,具有可移植性,一直維護並支持SSH-2協議,目前很多操作系統中默認安裝的版本。
2.SSH加密原理
互聯網上的數據傳輸,若未經加密,請求可能會被其他惡意攔截輕松獲取賬號密碼等信息,可通過數據加密的方式進行避免。加密的方式主要有兩種:
-
對稱加密(秘鑰加密),即客戶端和服務端使用同一套秘鑰對數據進行加密和解密,如下圖1所示。對稱加密的加密強度高,破解難度大。但是在多個客戶端和服務端安全的保存秘鑰是一個比較困難的操作,一個秘鑰被泄露,則整個系統會失去安全性。
-
非對稱加密(公鑰加密),為解決一個秘鑰的問題,非對稱加密應運而生。非對稱加密有一個公鑰和一個私鑰,公鑰加密后的數據只能通過對應的私鑰解密(反之亦然),而通過公鑰推出私鑰的可能性微乎其微。SSH即通過非對稱加密完成用戶登錄。
3.SSH工作流程
從客戶端的角度來看,SSH提供兩種級別的安全驗證。分別為基於口令(密碼)的安全驗證和基於公鑰的安全驗證。
-
密碼登錄:密碼登錄流程如下圖2所示。
Server收到Client用戶的登錄請求,Server將自己的公鑰發送給用戶;
Client使用公鑰將自己的密碼加密
Client將加密后的數據發送至Server端
Server端使用對應的私鑰解密數據,然后驗證其合法性
如果密碼正確,Server同意用戶登錄
私鑰是Server端獨有的,從而保證了網絡傳輸過程中登錄數據的安全性。但是實施的過程中存在一個風險:比如攻擊者插在用戶與遠程主機間,冒充Server端將偽造的公鑰發送給用戶,即可獲取用戶的密碼登錄遠程主機。這就是所謂的中間人攻擊。
SSH設計通過口令確認的方式避免中間人攻擊。如果用戶是第一次登錄Server,系統會出現如下提示:
ssh xxx@xxx
The authenticity of host 'host (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
提示的信息主要表達的意思是:“無法確認主機xxx的真實性,其公鑰指紋為xxx,是否繼續登錄?”由於公鑰長度較長難以比對,提示信息中將其經過MD5計算轉換為128位的指紋便於比較。而為確保用戶能比對公鑰指紋,Server需在自己的網站上貼出自己的公鑰指紋用於用戶核對。
若用戶同意連接該Server后,系統會提示用戶該host已被確認並被追加到文件known_hosts文件中以便下次登錄時跳過警告。然后即可輸入密碼按上述流程登錄。
每個SSH用戶(client端)都有自己的known_hosts文件, 此外系統也有一個這樣的文件,通常是/etc/ssh/ssh_known_hosts,保存一些對所有用戶都可信賴的遠程主機的公鑰。
-
公鑰登錄:密碼登錄的一個問題在於,每次登錄都要輸入密碼。為避免多次登錄的麻煩,SSH提供了另一種可以免密的登錄方式:公鑰登錄。
Client將自己的公鑰存放在Server端,追加到authorized_keys文件中。
Server端接收到Client的連接請求后,會在authorized_keys中匹配到Client的公鑰pubKey,並生成隨機數R,用Client的公鑰對該隨機數進行加密得到pubKey(R)
,然后將加密后信息發送給Client。
Client端通過私鑰進行解密得到隨機數R,然后對隨機數R和本次會話的SessionKey利用MD5生成摘要Digest1,發送給Server端。
Server端會也會對R和SessionKey利用同樣摘要算法生成Digest2。
Server端會最后比較Digest1和Digest2是否相同,完成認證過程。
此后登錄服務器就不再需要密碼。比如git使用SSH登錄,就可以在git下設置和管理SSH公鑰,如下圖所示。
4.SSH密鑰相關工具
依托於不同的操作系統,SSH密鑰生成和客戶端登錄各有其不同的工具。
Linux系統 |
Windows系統 |
|
生成密鑰 |
ssh-keygen |
keygen.exe Xshell |
客戶端登錄 |
ssh命令 |
Putty Xshell |
5.SSH密鑰格式
由SSH的發展歷史可見,SSH有SSH1.x、SSH2.x(IETF)、openssh等不同的版本,因此也定義了不同的密鑰格式。puttygen.exe可生成IETF格式的密鑰,ssh-kengen生成openssh格式的密鑰,xshell則可選擇所需格式。
-
SSH1格式:公鑰格式為所有字段以單個空格符分隔,各字段依次為選項、位數、指數、系數、注釋。第一個字段是可選的,表示該條目(行)是否以數字開頭,選項字段不會以數字開頭。最后一個字段注釋,如果在生成密鑰時沒有給定注釋,默認注釋為密鑰的創建者(一般就是 username@hostname 這種格式),注釋僅僅是提供給用戶查看密鑰時作為一個辨識標記,在 SSH 使用中沒有任何作用。
1024 35 127622522440000403693297547695512386039512623330270038753455316326495028304745444916417839627801075110249968608231245340093104912581642154883517309431162302400461903792227044870802907303974666069054112219556551766494201399889464578628657768414291418705994169562594444590440509069669981690177202614753409732391 ting@test.com
-
IETF格式
---- BEGIN SSH2 PUBLIC KEY ----
AAAAB3NzaC1yc2EAAAABIwAAAIEAtb2RtaDk8zTC28y20mHxLV
swAQDl4rCno3t/kfFhW1oRQxF7kQSQ6cg0y9K7stK7Vb6tCZED
LA39jVKHEQpzgQ+sb17691QtaFyBubMn1hpw/1fDq2W2lDL9C/
QmbjO7pDi6mnXTXxBsxF3PgLkck3KZtaafLe/uwTCB3behjyc=
---- END SSH2 PUBLIC KEY ----
-
openssh格式:公鑰格式為所有字段以單個空格符分隔,各字段依次為選項、密鑰類型(keytype)、base64編碼后的密鑰、注釋。第一個字段是可選的,表示該條目(行)是否以數字開頭,選項字段不會以數字開頭。最后一個字段注釋,如果在生成密鑰時沒有給定注釋,默認注釋為密鑰的創建者(一般就是 username@hostname 這種格式),注釋僅僅是提供給用戶查看密鑰時作為一個辨識標記,在 SSH 使用中沒有任何作用。密鑰類型(keytype)可能是 ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-ed25519, ssh-dss 或 ssh-rsa。
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAtb2RtaDk8zTC28y20mHxLVswAQDl4rCno3t/kfFhW1oRQxF7kQSQ6cg0y9K7stK7Vb6tCZEDLA39jVKHEQpzgQ+sb17691QtaFyBubMn1hpw/1fDq2W2lDL9C/QmbjO7pDi6mnXTXxBsxF3PgLkck3KZtaafLe/uwTCB3behjyc= ting
參考文章:
-
《圖解SSH原理》
https://www.jianshu.com/p/33461b619d53
-
《SSH的發展歷程與基本原理》
https://www.cnblogs.com/harrymore/p/8627345.html#_label1_3
-
《[Linux] ssh-key 公鑰文件格式》
https://www.cnblogs.com/ifantastic/p/3984544.html
-
《SSH原理與運用(一):遠程登錄》
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
-
《SSH密鑰對登錄的原理和實踐》
https://www.cnblogs.com/zhouhaibing/p/7679706.html