作者neversay (子不語)
看板Soft_Job
標題[技術]金鑰認證設定好,遠端登入沒煩惱。
時間Sat Aug 9 19:35:30 2014
網誌版 (運用貧瘠的美術能力想把金鑰認證流程畫出來 XD):
http://neversaycoding.tumblr.com/post/94238914127
最近在玩Github與線上IDE諸如Koding或Nitrous.IO,在玩這些平台的時候,常常
有些跨平台的需求,諸如:
* 想把Github上的專案抓進本機,然後修改後上傳回Github。
* 想從線上IDE的虛擬機器裡把Github上的專案抓下來修改並上傳。
* 想要從本機用SSH登入Koding或Nitrous.IO等線上IDE的終端機。
總之,各種登入遠端,或是把專案傳到遠端平台,其實都需要一些特殊設定才能達
成。這篇就來小記一下SSH金鑰認證的原理跟設定。
---------------------------------------------------------------------------
首先,在設定SSH金鑰前,我們最好對SSH的認證機制有些了解,這樣才能在一堆設
定裡面理清頭緒,不被搞得昏頭賺向。
SSH這個通訊方法底層使用的是不對稱加解密演算法。跟一般對稱加解密演算法用同
一把鑰匙加解密不同,不對稱演算法會產生兩把鑰匙,一把自己保管的私鑰,一把可
以亂給人的公鑰。
公鑰加密的訊息只有私鑰可以解密,反過來私鑰加密的訊息也只有
公鑰能解密。更奇妙的是,公鑰加密的東西無法用公鑰解密,私鑰也是一樣的情形。
而公鑰與私鑰之間沒有簡明易解的關係,所以就算拿到公鑰只能用暴力法,也沒辦法
在合理時間內破解出私鑰是什麼。
而Github與各大線上IDE用的都是SSH協定,避免你與主機之間的資料不經加密在網路
上流傳被他人攔截。(順帶一提,PTT等預設使用telnet協定的網站是沒有加密的,
所以PTT的密碼千萬別跟重要網站的密碼一致,否則被盜就慘了。)
而使用SSH來與遠方的主機進行數據交換時,有兩種認證方式:
第一種是帳號密碼的驗證法,每次使用者用SSH登入遠端主機或從主機拷貝檔案,就
必須輸入帳號密碼。這種方法的問題在於每次登入都必須輸入密碼,除了不方便之
外,讓密碼在網路上傳來傳去總是有點讓人毛毛的,雖然這些密碼都被加密了,但
是機敏資訊能夠不外曝就不外曝。
第二種方式叫金鑰驗證法。要用這方法,使用者必須在自己的機器上也產生私鑰與
公鑰,然後把公鑰擺在遠端主機的指定位置上。由於第一次登入遠端主機時就已經
得到了該主機的公鑰,所以一旦你將你的公鑰擺上去,就會形成雙方都有對方的公
鑰的情況,接下來就可以拿來做雙方驗證了。驗證步驟是:
1.訪客對遠方主機發出請求,把訪客的帳號與訪客的公鑰傳給遠方主機。
http://tinyurl.com/pgq42yx
2.遠方主機根據帳號找到該訪客之前上傳的公鑰做比對,如果完全一樣就代表該訪
客事先已經設定公鑰,所以可以繼續驗證程序。
3.遠方主機隨機產生一段暗號,用訪客的公鑰加密,把加密文字回傳給訪客。
http://tinyurl.com/qbuh4nr
4.訪客用訪客的私鑰解密該暗號。
http://tinyurl.com/l543nyh
5.用遠方主機的公鑰加密同一暗號。
http://tinyurl.com/nr7ahh5
6.將加密暗號回傳給主機。
http://tinyurl.com/p68dojb
7.遠方主機用遠方主機的私鑰解密該段文字得到原本的暗號。這樣主機就知道這個
訪客擁有正確的私鑰,身分確認無誤。
http://tinyurl.com/nhjm8wh
整個流程使用者完全不用輸入密碼,雙方在網路上傳遞的都是加密過的隨機字串。
攔截者就算攔到了該字串也沒多大用處,因為這明文沒有包含任何機敏資訊。不能
用它來猜測破解私鑰。
總而言之,金鑰認證的方法關鍵在於雙方都要有對方的公鑰,而且自己的私鑰不能
外流。這樣的話就能做到不需要密碼也能讓雙方互相認證。
-------------------------------------------------------------------------
接下來談談各個對開發者很重要的網路平台目前是怎麼使用金鑰認證的。
首先,你必須生成私鑰與公鑰,如果你是使用MAC或Linux,那將SSH套件安裝好之後
就可以用鳥哥的私房菜或Github的說明頁提到的方法產生公私鑰,如果是Window則
要用這裡(
http://www.vixual.net/blog/archives/190 )提到的方法產生。
在Github等平台上想把自己的專案抓下來本機電腦,修改再上傳,就必須經過認證
步驟,而Github的認證方法就是使用金鑰認證。
1.當公私鑰產生完成後,你會在特定的檔案位置看到公鑰,例如Linux/MAC上公鑰儲
存在 ~/.ssh/id_rsa.pub 或者 ~/.ssh/id_dsa.pub 裡面,看你當初是用哪個演算
法產生金鑰。然後登入Github,在右上的選單列選擇”Account Setting”進入帳號
設定。
2.在帳號設定裡面左方選單選擇”SSH Keys",接著選擇"Add SSH key",把公鑰字
串整個複製貼上,再按下"Add key"就完成了。
3.設定完成後,理論上從你的電腦向Github的讀取(git pull)與修改(git push)
指令都不會被存取拒絕。
4.如果你有在使用線上IDE配合Github的話,通常線上IDE的虛擬機器也會事先產生
公私鑰,以利使用者設定金鑰認證。下圖就是我的Github上儲存的公鑰,從我的
電腦、Koding的虛擬機器以及Nitrous.IO的虛擬機器上各一把:
http://tinyurl.com/n42mkel
------------------------------------------------------------------------
金鑰認證的另一種用法,就是讓線上IDE的使用者可以從本機電腦登入線上IDE產生
的虛擬機器。畢竟對程式的老手來說,有時候直接遠端登入SSH會比從網頁瀏覽器
的終端機介面來得快,反應也比較迅速。
(瀏覽器有時候會頓頓的,且在不同頁面切換有時要靠滑鼠點來點去有點煩。)
在線上IDE的設定方法跟Github類似,只要找到相對應的設定頁面,把自己電腦產
生的公鑰設定進去就好了。
Koding的設定說明頁面在這裡
(
http://learn.koding.com/guides/ssh-into-your-vm/ )。
而Nitrous.IO的設定頁面在這邊(
http://help.nitrous.io/ssh-add/ )。
這樣,不知道大家是否對SSH等的金鑰認證的原理,還有它現今在網路服務的應用
有了認識?
Happy Coding Day!
參考資料:
JosephJ的進階說明:
http://josephj.com/article/understand-ssh-key/
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 50.156.87.148
※ 文章網址: http://www.ptt.cc/bbs/Soft_Job/M.1407584133.A.76D.html
→ ssccg:公鑰與私鑰之間沒有數學上的關係?? 08/09 19:48
推 banjmin:質疑同樓上 rsa兩個大質數 同餘 費馬小定理不是數學嗎? M 08/09 20:07
→ banjmin:iller-Rabin Primality Testing不是數學嗎?分享公開金鑰 08/09 20:07
→ banjmin:原理是好事 但是不要誤導 08/09 20:07
→ kuso0516:可能是想說只有公鑰沒辦法用數學的方式推導出私鑰是哪隻? 08/09 22:30
→ DrTech: 這是不懂還是為了讓初學者了解,而簡化太多觀念阿 08/10 01:20
→ DrTech: 整篇文章完全忽略 Mutual Authentication,別人發的 08/10 01:21
→ DrTech: Public key ,完全不做身分驗證。 08/10 01:21
推 DrTech: 用公鑰來判斷是否為冒牌貨的言論更是誤導。公鑰是公開的 08/10 01:26
→ DrTech: 任何人都可取得。 08/10 01:26
→ neversay: 沒有數學關係這句話我拿掉重回好幾次......我比較想表達 08/10 02:34
→ neversay: 的是只有暴力法才能從公鑰推出私鑰 08/10 02:34
→ neversay: (在理想情況上) 08/10 02:34
→ neversay: 回DrTech大: 我把與SSH server一開始的雙向認證略過, 08/10 02:45
→ neversay: 因為在做金鑰認證的設定之前雙向認證應該就做完了 08/10 02:46
→ neversay: 要不然也沒辦法登入遠端server放authorized_key 08/10 02:46
→ neversay: 如果要把最初的雙向認證加進來會複雜,所以簡化了 08/10 02:53
→ neversay: 至於用公鑰驗證冒牌貨,是基於兩種情形: 08/10 02:54
→ neversay: 1.給不符合的公鑰,系統會直接拒絕剩下的步驟,改用 08/10 02:54
→ neversay: 傳統的帳號密碼的方式,或者根本就拒絕連線 08/10 02:55
→ neversay: 2.公鑰Pa與主機上儲存的一致,主機就會用演算法E加密 08/10 02:56
→ neversay: 隨機字串S變成E(Pa, S)傳回給訪客,然後訪客必須用私鑰 08/10 02:56
→ neversay: Pa'解密還原出S,接著用server的公鑰Pb也把S加密成 08/10 02:57
→ neversay: E(Pb, S),傳回給server。讓server解密取回S 08/10 02:58
→ neversay: 這樣就證明了訪客: 08/10 02:58
→ neversay: 1.擁有與之前設定的一樣的公鑰 08/10 02:59
→ neversay: 2.該訪客擁有正確的私鑰,所以真的是公鑰的產生者。 08/10 02:59
→ neversay: 換句話說誰都能用公鑰Pa給server求取連線,但是只有 08/10 03:03
→ neversay: 真正的私鑰擁有者能夠解密server給的隨機字串 08/10 03:04
改掉公鑰私鑰間的數學關係的文字,還有改掉我自己的推文的錯字 XD
※ 編輯: neversay (50.156.87.148), 08/10/2014 03:08:49
→ ssccg: 可是用公鑰基本上是由私鑰推出來的 08/10 05:46
→ ssccg: 想要表達公鑰推私鑰很困難就直接這樣寫,何必扯什麼數學關 08/10 05:46
→ ssccg: 係,成對的公私鑰本身就已經是數學關係了 08/10 05:49
※ 編輯: neversay (50.156.87.148), 08/10/2014 06:26:27
→ neversay: 有道理,我把用詞改掉...... 08/10 06:29
然後把公鑰與冒牌貨的字修掉,因為能不能驗證是否冒牌要等到最後一步才知道。
※ 編輯: neversay (50.156.87.148), 08/10/2014 06:38:32
→ DrTech: 感謝你的回應,讓我更了解整個過程。 08/10 11:35
→ neversay: 不客氣 :P 08/10 11:55