1. 程式人生 > >ssh原理以及與https的區別

ssh原理以及與https的區別

最近在使用雲伺服器的時候使用到了ssh去做登陸驗證。關於ssh的使用原理,公鑰和金鑰如果對伺服器的登陸做驗證的。以及對稱加密和非對稱加密的基本原理,這裡做一個比較詳細的歸納和總結。

一、明白的以下幾個概念:

know_host : 儲存 已經確保正常、可以安全連線的所有伺服器(hosts)的公鑰

authorized_hosts : 儲存 已經認證的客戶端的公鑰

public key :公鑰

private key :私鑰

使用ssh和https有什麼不同:

HTTPS:使用https url克隆對初學者來說會比較方便,複製https url然後到git Bash裡面直接用clone命令克隆到本地就好了,但是每次fetch和push程式碼都需要輸入賬號和密碼,這也是https方式的麻煩之處(發現了

https免密登入的方式)。
SSH:使用SSH url克隆卻需要在克隆之前先配置和新增好SSH key,因此,如果你想要使用SSH url克隆的話,你必須是這個專案的擁有者或管理員,否則你是無法新增SSH key的。另外ssh預設是每次fetch和push程式碼都不需要輸入賬號和密碼,如果你想要每次都輸入賬號密碼才能進行fetch和push也可以另外進行設定

生成SSH Key的基本命令:

#步驟1:
cd  ~/.ssh ls
#這兩個命令就是檢查是否已經存在id_rsa.pub或id_dsa.pub檔案,如果檔案已經存在,那麼你可以跳過步驟2

#步驟2:建立一個SSH Key 
ssh-keygen -t rsa -C "你的email地址"
#程式碼引數含義: 
#-t指定金鑰型別,預設是rsa,可以省略。 
#-C設定註釋文字,比如郵箱。 
#-f指定金鑰檔案儲存檔名。 

二、關於ssh

 SSH是一種網路協議,用於計算機之間的加密登入。如果一個使用者從本地計算機,使用SSH協議登入另一臺遠端計算機,我們就可以認為,這種登入是安全的,即使被中途截獲,密碼也不會洩露。

最早的時候,網際網路通訊都是明文通訊,一旦被截獲,內容就暴露無疑。1995年,芬蘭學者Tatu Ylonen設計了SSH協議,將登入資訊全部加密,成為網際網路安全的一個基本解決方案,迅速在全世界獲得推廣,目前已經成為Linux系統的標準配置。

三、基本用法

ssh [email protected]

四、對稱加密和非對稱加密的區別

首先想到的實現方案肯定是對資料進行加密。加密的方式主要有兩種:

  • 對稱加密(也稱為祕鑰加密)
  • 非對稱加密(也稱公鑰加密)

所謂對稱加密,指加密解密使用同一套祕鑰。如下圖所示:

1、用於加密資料的元件和用於解密資料的元件,兩者之間的關聯性決定了該種加密方式是對稱型的還是非對稱型的。

對稱加密採用同一個金鑰加密和解密資料。也就是說,任意兩個持有同樣金鑰的人就可以在相互之間傳遞加密資訊並解密。

該種加密方式常被稱為“共同的祕密(shared secret)”式加密或者“祕密的鑰匙(secret key)”式加密。通常情況下,所有的操作都使用同一個金鑰,或者一對關聯度非常高、使得接收方能夠很容易的推斷出傳送方使用的金鑰的金鑰對。

SSH使用對稱金鑰為整個連線過程加密。眾所周知的公鑰/私鑰(public/private)是非對稱金鑰對,然而它們僅僅用於身份驗證的過程,而沒有用在傳輸過程。對稱加密可以保護密碼驗證過程不受嗅探(snooping)的威脅。

該對稱金鑰由客戶端與伺服器端共同建立,生成的金鑰不告知任何第三方。建立金鑰的過程涉及一個金鑰交換演算法(key exchange algorithm),使用該演算法時,客戶端和伺服器端根據共享的部分公共資料加上指定的祕密資料分別獨立生成同樣一個金鑰(下文將詳細介紹這個過程)。

該過程建立的對稱加密金鑰是基於會話(session)的,負責對伺服器和客戶端之間傳輸的資料進行加密。建立後,其餘的所有資料傳輸都會經過該金鑰的加密。這個過程在認證客戶端之前執行。

SSH可以配置不同的對稱加密法(symmetrical cipher system),包括AES、Blowfish、3DES、CAST128、以及Arcfour。伺服器和客戶端都可以選擇其使用的加密法,最終使用的加密法一般由機器上加密法列表的排序決定:客戶端加密法列表上出現的第一個伺服器端也支援的加密演算法,將用於雙方加密傳輸的實現。

Ubuntu 14.04的預設列表順序如下(客戶端和伺服器端通用):aes128-ctr、aes192-ctr,aes256-ctr、arcfour256、arcfour128、[email protected][email protected][email protected]、aes128-cbc、blowfish-cbc、cast128-cbc、aes192-cbc、aes256-cbc、arcfour。

也就是說,如果是兩臺Ubuntu 14.04之間進行資料傳輸,則它們總會使用aes128-ctr加密演算法(除非做過另外的配置)。

 對稱加密-Client端


對稱加密-Server端


2、非對稱加密有兩個金鑰:"公鑰"和"私鑰"。

特性:

公鑰加密後的密文,只能通過其對應的私鑰進行解密。

通過公鑰推理出私鑰的可能性微乎其微。

非對稱加密的傳送與接收需要使用兩個金鑰,這兩個金鑰是相互關聯的,一個叫做私鑰(private key),另一個叫做公鑰(public key)。

公鑰可以共享給其他人,僅僅持有公鑰是無法推匯出私鑰的。從數學的實現上,公鑰加密的資訊僅僅可以由私鑰解密(而不能由公鑰自己解密),私鑰加密的資訊也不能用公鑰解密。這是一個單向的過程。

私鑰必須要嚴格保密,不可與其他人共享。私鑰的保密是整個加密正規化安全性的關鍵。該正規化假設:持有私鑰是解密的唯一方式。如果一臺主機能夠解密由公鑰加密過的資訊,這隻能表示它掌握著對應的金鑰。

SSH在以下幾個節點採用了非對稱加密。首先是一開始建立用於連線的對稱加密時的金鑰交換過程(key exchange)。在這一階段,伺服器和客戶端都各自生成了臨時的公鑰/私鑰對,以計算出同一個用於連線加密的共享金鑰。

其次是廣為人知的SSH身份驗證過程。SSH金鑰對用於讓伺服器驗證一個客戶端的身份。金鑰對在客戶端上生成,其中的公鑰上傳至遠端伺服器,儲存在~/.ssh目錄下一個叫做authorized_keys的檔案裡。

安全連線建立後,伺服器就會觸發身份驗證過程。伺服器會用其檔案裡的公鑰加密一條資訊發給客戶端,如果客戶端能夠解密出正確的資訊,則證明了它持有對應的私鑰,然後伺服器才會對該客戶端開放自己的環境。

非對稱加密原理圖:


登入流程:

  1. 遠端Server收到Client端使用者TopGun的登入請求,Server把自己的公鑰發給使用者。

  2. Client使用這個公鑰,將密碼進行加密。

  3. Client將加密的密碼傳送給Server端。

  4. 遠端Server用自己的私鑰,解密登入密碼,然後驗證其合法性。

  5. 若驗證結果,給Client相應的響應。

補充:這一種登陸方式是通過口令的方式登陸。需要每次輸入一次密碼,密碼輸入後通過服務端的公鑰加密後進行傳輸到服務端,服務端的私鑰進行解密。 

五、中間人攻擊

SSH之所以能夠保證安全,原因在於它採用了公鑰加密。

整個過程如上圖所示:

(1)遠端主機收到使用者的登入請求,把自己的公鑰發給使用者。

(2)使用者使用這個公鑰,將登入密碼加密後,傳送回來。

(3)遠端主機用自己的私鑰,解密登入密碼,如果密碼正確,就同意使用者登入。

這個過程本身是安全的,但是實施的時候存在一個風險:

Client端如何保證接受到的公鑰就是目標Server端的?,如果一個攻擊者中途攔截Client的登入請求,向其傳送自己的公鑰,Client端用攻擊者的公鑰進行資料加密。攻擊者接收到加密資訊後再用自己的私鑰進行解密,不就竊取了Client的登入資訊了嗎?

如果有人截獲了登入請求,然後冒充遠端主機,將偽造的公鑰發給使用者,那麼使用者很難辨別真偽。因為不像https協議,SSH協議的公鑰是沒有證書中心(CA)公證的,也就是說,都是自己簽發的。可以設想具體場景,如果攻擊者插在使用者與遠端主機之間(比如在公共的wifi區域),用偽造的公鑰,獲取使用者的登入密碼。再用這個密碼登入遠端主機,那麼SSH的安全機制就蕩然無存了。這種風險就是著名的"中間人攻擊"(Man-in-the-middle attack)。

以使用者TopGun為例,如圖四:

六、解決中間人攻擊方法

1、口令登入(基於口令的認證)

從上面的描述可以看出,問題就在於如何對Server的公鑰進行認證?在https中可以通過CA來進行公證,可是SSH的publish key和private key都是自己生成的,沒法公證。只能通過Client端自己對公鑰進行確認。

通常在第一次登入的時候,系統會出現下面提示資訊:

$ ssh [email protected]
The authenticity of host 'host (12.18.429.21)' 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)?

上面的資訊說的是:無法確認主機host(12.18.429.21)的真實性,不過知道它的公鑰指紋,詢問你是否繼續連線?

所謂"公鑰指紋",是指公鑰長度較長(這裡採用RSA演算法,長達1024位),很難比對,所以對其進行MD5計算,將它變成一個128位的指紋。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再進行比較,就容易多了。

之所以用fingerprint代替key,主要是key過於長(RSA演算法生成的公鑰有1024位),很難直接比較。所以,對公鑰進行hash生成一個128位的指紋,這樣就方便比較了。

很自然的一個問題就是,使用者怎麼知道遠端主機的公鑰指紋應該是多少?

回答是沒有好辦法,遠端主機必須在自己的網站上貼出公鑰指紋,以便使用者自行核對,或者自己甄別host地址是否正確。

假定經過風險衡量以後(一般使用者直接就選擇yes吧),使用者決定接受這個遠端主機的公鑰。
  Are you sure you want to continue connecting (yes/no)? yes
系統會出現一句提示,表示host主機已經得到認可。
  Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
然後,會要求輸入密碼。
  Password: (enter password)
如果密碼正確,就可以登入了。

當遠端主機的公鑰被接受以後,它就會被儲存在檔案$HOME/.ssh/known_hosts之中。下次再連線這臺主機,系統就會認出它的公鑰已經儲存在本地了,從而跳過警告部分,直接提示輸入密碼。
每個SSH使用者都有自己的known_hosts檔案,此外系統也有一個這樣的檔案,通常是/etc/ssh/ssh_known_hosts,儲存一些對所有使用者都可信賴的遠端主機的公鑰。

我本地的known_hosts檔案,可以發現已經儲存了五個我覺得放心的伺服器(hosts)的公鑰

簡單說,當host已被確認,並被追加到檔案known_hosts中,下次連線只需要輸入密碼即可,之後的流程就按照圖3進行。

2、公鑰登入(基於公鑰的認證)

使用密碼登入,每次都必須輸入密碼,非常麻煩。好在SSH提供了另外一種可以免去輸入密碼過程的登入方式:公鑰登入。

所謂"公鑰登入",原理很簡單,就是使用者將自己的公鑰儲存在遠端主機上。

登入的時候,遠端主機會向用戶傳送一段隨機字串,使用者用自己的私鑰加密後,再發回來。遠端主機用事先儲存的公鑰進行解密,如果成功,就證明使用者是可信的,直接允許登入shell,不再要求密碼。

公鑰認證流程:

1. Client端使用者TopGun將自己的公鑰存放在Server上,追加在檔案authorized_keys中。

2. Server收到登入請求後,隨機生成一個字串str1,併發送給Client。

3. Client用自己的私鑰對字串str1進行加密。

4. 將加密後字串傳送給Server。

5. Server用之前儲存的公鑰進行解密,比較解密後的str2和str1。

6. 根據比較結果,返回客戶端登陸結果。

這種方法要求使用者必須提供自己的公鑰。如果沒有現成的,可以直接用ssh-keygen生成一個

執行上面的命令以後,系統會出現一系列提示,可以一路回車。其中有一個問題是,要不要對私鑰設定口令(passphrase),如果擔心私鑰的安全,這裡可以設定一個。

執行結束以後,在$HOME/.ssh/目錄下,會新生成兩個檔案:id_rsa.pub和id_rsa。前者是你的公鑰,後者是你的私鑰。

比如,我需要用使用者user登入host伺服器,只需再輸入下面的命令,將公鑰傳送到遠端主機host上面:

$ ssh-copy-id [email protected]

好了,從此你再登入,就不需要輸入密碼了。

如果還是不行,就開啟遠端主機的/etc/ssh/sshd_config這個檔案,檢查下面幾行前面"#"註釋是否取掉。
  RSAAuthentication yes
  PubkeyAuthentication yes
  AuthorizedKeysFile .ssh/authorized_keys
然後,重啟遠端主機的ssh服務。
  // ubuntu系統
  service ssh restart
  // debian系統
  /etc/init.d/ssh restart

3、什麼是authorized_keys檔案?

遠端主機將使用者的公鑰,儲存在登入後的使用者主目錄的$HOME/.ssh/authorized_keys檔案中。公鑰就是一段字串,只要把它追加在authorized_keys檔案的末尾就行了。

這裡不使用上面的ssh-copy-id命令,改用下面的命令,解釋公鑰的儲存過程:

$ ssh [email protected] 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
這條命令由多個語句組成,依次分解開來看:(1)"$ ssh [email protected]",表示登入遠端主機;(2)單引號中的mkdir .ssh && cat >> .ssh/authorized_keys,表示登入後在遠端shell上執行的命令:(3)"$ mkdir -p .ssh"的作用是,如果使用者主目錄中的.ssh目錄不存在,就建立一個;(4)'cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub的作用是,將本地的公鑰檔案~/.ssh/id_rsa.pub,重定向追加到遠端檔案authorized_keys的末尾。
寫入authorized_keys檔案後,公鑰登入的設定就完成了。

相關推薦

ssh原理以及https區別

最近在使用雲伺服器的時候使用到了ssh去做登陸驗證。關於ssh的使用原理,公鑰和金鑰如果對伺服器的登陸做驗證的。以及對稱加密和非對稱加密的基本原理,這裡做一個比較詳細的歸納和總結。一、明白的以下幾個概念:know_host : 儲存 已經確保正常、可以安全連線的所有伺服器(h

HashMap底層原理以及ConCurrentHashMap區別

clas put level shm segment 區別 一個 bucket link   HashMap基於hashing原理,我們通過put()和get()方法儲存和獲取對象。當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashc

HashMap工作原理以及HashTable的區別--面試題

每當往hashmap裡面存放key-value對的時候,都會為它們例項化一個Entry物件,這個Entry物件就會儲存在前面提到的Entry陣列table中。現在你一定很想知道,上面建立的Entry物件將會存放在具體哪個位置(在table中的精確位置)。答案就是,根據ke

Mybatis整理系列(01)————傳入參數方式以及#{}${}的區別

Java實體類 erb code {} param mean ctu obj result 一、在MyBatis的select、insert、update、delete這些元素中都提到了parameterType這個屬性。MyBatis現在可以使用的parameterTyp

(轉)HashMap底層實現原理/HashMapHashTable區別/HashMapHashSet區別

eem 實現原理 ger 銀行 索引 target 聲明 到你 們的 ①HashMap的工作原理 HashMap基於hashing原理,我們通過put()和get()方法儲存和獲取對象。當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算has

應用層(http協議) httphttps區別

在協議分層的TCP/IP(或四層)通訊協議採用了5層的層級結構,5層分別包括:應用層、傳輸層、網路層、資料鏈路層、物理層。5層一些簡單功能和著名協議可參考這篇部落格:https://blog.csdn.net/sophia__yu/article/details/82717115 一.應用層

如何為虛擬機器中的Ubuntu17安裝SSH服務以及XShell建立連線

本人在Ubuntu中安裝SSH時,在未獲取root許可權的情況下是不能安裝SSH,因此,本人通過以下步驟獲取得到root許可權,獲取步驟如下: 1.首先輸入: sudo passwd root 2.Enter new UNIX password:(在這裡輸入密碼) 3.retype

c++子類繼承父類函式呼叫特性原理以及java的對比

c++ c++中子類繼承了父類,子類物件的函式和變數會接著新增在父類物件的記憶體後面,以此類推。。。 如果c++中父類的那個變數或者函式宣告為virtual虛擬函式,那麼子類物件的同名函式就直接覆蓋了(即在記憶體中真正的覆蓋,父類的這個函式已經不在了)父類物件的這個函式 如

httphttps區別https是如何保障安全性

區別: 1、加密:http協議對傳輸的資料不進行加密;https協議對傳輸的資料使用SSL安全協議進行加密,https加密需要CA簽發的證書。  2、埠:http協議使用TCP的80埠;https協議使用TCP的443埠  3、網路分層模型:http可以明確是位於應用層;http

Jetty 的工作原理以及 Tomcat 的比較

Jetty 目前的是一個比較被看好的 Servlet 引擎,它的架構比較簡單,也是一個可擴充套件性和非常靈活的應用伺服器,它有一個基本資料模型,這個資料模型就是 Handler,所有可以被擴充套件的元件都可以作為一個 Handler,新增到 Server 中,Jetty 就是幫你管理這些 Handler。

HashMap底層實現原理/HashMapHashTable區別/HashMapHashSet區別

①HashMap的工作原理 HashMap基於hashing原理,我們通過put()和get()方法儲存和獲取物件。當我們將鍵值對傳遞給put()方法時,它呼叫鍵物件的hashCode()方法來計算hashcode,讓後找到bucket位置來儲存值物件。當獲取物件時,通

HashMap儲存原理以及hashcode、equals方法的關係

一、HashMap 儲存/讀取資料原理: 先放原始碼: public class HashMap<K, V> extends AbstractMap<K, V>

makefile中for的用法以及$$$的區別

$$表示$,用來shell下引用變數,而$A或者$(A)則是Makefile的變數。 下面舉例說明: rule_1: for i in 1 2 3 4 5; do echo $(i); done 上面的程式碼不會連續列印 1 2 3 4 5 但下面的程式碼會:

Oracle的left join中on和where的區別以及(+)的區別

資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者。       在使用left jion時,on和where條件的區別如下: 1、 on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。 2、where條件是在臨時表生成好後

NSSet型別 以及NSArray區別

NSSet到底什麼型別,其實它和NSArray功能性質一樣,用於儲存物件,屬於集合; NSSet  , NSMutableSet類宣告程式設計介面物件,無序的集合,在記憶體中儲存方式是不連續的,不像NSArray(是有序的集合)類宣告程式設計介面物件是有序集合,在記憶體中儲

httphttps區別詳解

在URL前加https://字首表明是用SSL加密的。你的電腦與伺服器之間收發的資訊傳輸將更加安全。Web伺服器啟用SSL需要獲得一個伺服器證書並將該證書與要使用SSL的伺服器繫結。http和https使用的是完全不同的連線方式,用的埠也不一樣,前者是80,後者是443。

httphttps區別以及oauth簡單原理

http與https協議的區別 下面我們就來說所http與https的一些區別到底有什麼,他們兩個都是網路上最為廣泛的網路協議,首先呢在安全上面來說http協議他在傳輸資料的時候它對所傳輸的資料是不進行加密的,也就是進行明文格式進行傳輸的,因此http協議如果用於傳輸隱私類的資料是非常不

區塊鏈100講:HTTPS協議的原理及其HTTP協議的區別

1 HTTPS協議是什麼 https協議比http協議多了一個s,字面意思上s=secure(安全)。它跟http協議一樣都是應用層協議,都是工作在TCP協議之上。 只不過https協議在傳輸過程中的資料都是經過了加密。本質上HTTPS協議就是在TCP協議之上又加了一層SS

Eureka的工作原理以及ZooKeeper的區別

Eureka的工作原理以及它與ZooKeeper的區別 1、Eureka 簡介: Eureka 是 Netflix 出品的用於實現服務註冊和發現的工具。 Spring Cloud 集成了 Eureka,並提供了開箱即用的支援。其中, Eureka 又可細分為 Eureka Server 和

git拉程式碼時, https git clonessh git clone之間的區別

首先看一下兩種使用方法的面相: https git clone是長這樣的:     https://gitee.com/hillmay/catmiao.git   ssh git clone是長這樣的: [email