天天看點

大話https演化過程(對稱加密、非對稱加密、公鑰、私鑰、數字簽名、數字證書)

大話https演化過程(包括概念:對稱加密、非對稱加密、公鑰、私鑰、數字簽名、數字證書、https通路全過程)

在網絡上發送資料是非常不安全的,非常容易被劫持或是被篡改,是以每次定向發送資料你都可以視為在廣播,每次定向接收資料都可以視為在廣收。而建立安全通道的難度和成本都很高,甚至安全性都不一定靠譜。

在這樣的情境下,F需要向S發送一段隻有S才能看的資訊msg,它要如何做呢?

很容易想到一個最直接的方法:給這段資訊加密,隻有F和S有密鑰(加密與解密采用相同的算法和密鑰),這樣F廣播的資訊雖然都能看到,但是隻有S才能解密看懂

  1. 這個方法不用我說也肯定哪兒有問題:F的密鑰是怎麼傳到S手上的呢?(密鑰也是一段資料,也有被劫持的風險)

于是這個方法輕易地跌入了死循環的陷阱,那怎麼辦呢,看起來好像事情陷入了僵局。但牛逼的密碼學家想到了一個妙招,他們發明了一種神奇的鑰匙,用這種神奇的鑰匙打破了僵局

  1. 神奇的鑰匙不是一把,而是一套兩把,比如A和B,它們的特點是:A加密的資料隻有B能解密,B加密的資料隻有A能解密(這是怎麼實作的又是另外一回事,可以另外看相關的數學資料)
  2. 是這樣通過神奇鑰匙來解決問題的:(如果F需要向S發送一段隻有S才能看的資訊msg)
    1. 先配置設定給接收者S一套神奇鑰匙,然後S留一把給自己,叫做私鑰,比如sA,這把鑰匙不公開,隻給自己使用,另一把鑰匙S通過廣播發送給F(甚至是所有人),比如sB,這把鑰匙不僅随便你怎麼劫持,甚至幹脆公開,所有人都可以使用,叫做公鑰
    2. 然後F收到公鑰sB後,把要發送的msg用sB加密,再把密文msg通過廣播發送給S
    3. S收到密文msg後,使用sA進行解密,閱讀到内容
    4. 因為在互相傳送的過程中,隻有公鑰sB和用sB加密的密文msg被廣播了,即使他們都被劫持,劫持者也無法對msg進行解密,關鍵的能解密的鑰匙sA一直好好地呆在S手上,計劃通

這個方法不僅看起來非常巧妙,而且看起來也完美無缺,但即使如此,非常遺憾,它也存在問題,而且是兩個問題,雖然确切地說是一類問題

  1. 其實最開始的要求【F需要向S發送一段隻有S才能看的資訊msg】由于網絡的不安全性,它具體包括兩個方面
    1. 不能被偷看。除S之外的其他人無法閱讀msg
    2. 不能被篡改。收到的msg确實是F發的原版msg,不是假的或者修改過的
  2. 你确實解決了第一個方面,但是第二個方面你完全不能防範,因為雖然劫持者得到的公鑰sB不能對密文msg進行解密,但劫持者可以用公鑰sB來僞造另一份jmsg,然後裝作是F發送的msg送給S,S能對這個jmsg解密,而且解密之後并不能區分它是不是真的,假資訊同樣能對S造成危險(比如讓S給某個賬号打錢)
  3. 甚至由于同樣的原因,你有沒有惡寒地意識到另外一種危險的可能,那就是:最初F收到的公鑰sB會不會是僞造的呢?
  4. 這樣的話,其實你剛剛以為解決的第一個方面其實也沒有解決,因為:假如最初F收到的公鑰sB其實是劫持者發過來的假公鑰jB,那麼F就會用這個jB來對他要發送的msg進行加密,加密後廣播發出去,被劫持者劫持後他就能使用他的jA來解密,竊取資訊,任務失敗。(不考慮 最初F會收到多份公鑰、最後S收到的密文msg用sA無法解密 會引起懷疑,因為這個時候msg已經洩露了,而且引起懷疑之後問題還是在,還是需要解決)

這兩個問題中其中一個問題比較好解決:确定【S收到的資訊msg确實是F發送的】,沒有被篡改,也就是資訊要能确定地辨別自己的身份

  1. 好像能利用神奇鑰匙的另一個特點來解決問題:使用AB鑰匙配對的唯一性來辨別身份。大概是這樣的:
    1. 當發送者用私鑰對資訊進行加密後,接收者發現公鑰可以把接收的資訊解密,這就說明收到的資訊跟公鑰的主人是同一個人(假如收到的公鑰确實是他希望的發送者發來的話)
  2. 是以這裡就可以具體這樣做:
    1. 給F一套它的神奇鑰匙,F把fA作為私鑰,fB作為公鑰
    2. F發送msg時,用它的私鑰fA和S的公鑰sB對msg進行雙重加密
    3. S收到資訊msg後,先用fB對msg進行解密,确定這條資訊就是F發送來的,再用自己的私鑰再次解密以讀取資訊

上面這個方法公鑰身份的問題同樣懸而未決,是以回到前面,最大的問題還是:如何确定【F收到的公鑰sB确實是S發送的】,每一個公鑰sB要能确定地辨別自己的身份

  1. 簡單用上面同樣的方法想一下:
    1. S發送自己的公鑰sB前,要先用自己的私鑰sA對這個公鑰sB加密;之後F收到經過sA加密的公鑰sB後,如果使用sB能把它解密,那就說明這個被加密的資訊确實是S發來的
    2. 哈哈等等,你看的時候就發現了一個很大的不對勁吧,是的,這裡又出現了循環,而且非常明顯:F在收到sB之前并不能對經過sA加密的資訊解密,即使這個被加密的資訊中就是sB,是以這個傳送sB的方法行不通

那怎麼辦?明着傳公鑰會不知道是誰的,把身份加密進去傳公鑰對方又解不開密。身份肯定是要辨別的,那不用加密的方式辨別身份,換種方式辨別行不行啊?這樣對方确認身份的時候就不用解密,就不用擔心對方沒密鑰解不了密了

如果不行的話那就隻剩一個方法了,事先傳公鑰的時候要不就用一下安全通道嘞?是的,前面說的【建立安全通道的難度和成本都很高,甚至安全性都不一定靠譜】這幾個問題其實是可以通過拆分然後逐個攻破的

  1. 可拆分成這兩個次元:(這兩個次元其實也是安全領域内兩個永恒的主題)安全性和付出成本
  2. 安全性方面
    1. 對于個人使用者來說,你确實你難以在網絡上建構一條安全通道(因為你不是專業的搞安全的),但是如果你有一個靠譜的第三方機構的協助,你還是可能實作的
    2. 比如你把你的公鑰釋出到第三方機構,然後想發送給你資訊的人先去第三方機構上下載下傳你的公鑰,這樣你的公鑰就通過一條安全通道傳給了别人
  3. 付出成本方面
    1. 如果隻是像上一條這樣用這種方法建構安全通道的話,情況是這樣的:(假如F要發送資訊給S)
      1. 那麼S要事先把自己的公鑰釋出到第三方機構,F也要事先把自己的公鑰釋出到第三方機構
      2. 然後F在發送之前先上第三方機構擷取S的公鑰,之後F把資訊用S的公鑰加密,再用自己的私鑰加密
      3. 然後F把雙重加密後的資訊發送給S
      4. S收到資訊後要先上第三方機構擷取F的公鑰,之後把收到的資訊用F的公鑰解密确認是F發的資訊,再用自己的私鑰解密讀取資料
    2. 它會面臨這些問題:
      1. 第三方機構需要實時維護一個巨大的公鑰庫,而且越來越大,存儲和流量都是問題
      2. F給不同的對象發送資訊,都要事先上第三方機構擷取各種證書,而不能一次布置永久生效
      3. 正處于A和B連接配接過程中的時候,還需要另外去另一個地方C擷取某個東西,非常麻煩
    3. 是以這種利用第三方機構建構安全通道的方法需要一些改進

聰明的密碼學家想到了這個辦法:(假如F要發送資訊給S)

  1. 事先F和S都上第三方機構擷取第三方機構的公鑰
  2. 事先F和S都把自己的公鑰發給第三方機構,然後第三方機構對他們的公鑰用第三方機構的私鑰進行加密,得到被加密的公鑰叫做F和S的數字證書,傳回給F和S
  3. F先向S請求要S的數字證書
  4. 于是S把自己的數字證書發送給F
  5. F使用第三方的公鑰對數字證書進行解密,得到沒有錯的S的公鑰【為什麼沒有錯?下面要講】
  6. 然後F就使用S的這個公鑰對要發送的資訊進行加密,再用F自己的私鑰對這個資訊二次加密,同時附上自己的數字證書。F把這些資訊一塊發給S
  7. S在收到資訊後首先解密數字證書獲得了F的公鑰,然後用這個公鑰對資訊一次解密,能解開就說明發送資訊的人是證書裡寫的這個人,假如證書裡寫的是F,那麼就确定了F的身份,然後再用自己的私鑰對資訊進行二次解密,讀取資訊
  8. (這裡其實有點像前面說的,在公鑰上套一個數字證書,辨別了其身份,然後不用懷疑來懷疑去了,但為什麼數字證書就信了呢?)

為什麼用第三方的公鑰對數字證書進行解密這一過程能保證公鑰的身份呢?

  1. 這個問題嚴格說來,情境是這樣的:在你登入網站A時,收到一份使用數字證書私鑰加密的公鑰,如何能證明證書裡邊的公鑰是網站A的公鑰?
  2. 信任鍊條是這樣的:
    1. 你最開始要知道數字證書裡邊是什麼東西,主要有這兩個比對的東西:網站位址和網站的公鑰
    2. 首先你電腦裡記錄了所有能信任的頒發數字證書的公司以及他們的公鑰,這是你信任的基石,就像肯·湯普遜在他的《對深信不疑的信任》1983年獲得圖靈獎時的演說中說的一樣:你最終還是要絕對信任某一人,在這個問題上沒有第二條路可走
    3. 然後第一步,你檢查這份證書是不是你信任的公司頒發的,如果是,使用公鑰對這份證書進行解密,然後下一步
    4. 第二步,解密的結果是一個網站位址和網站公鑰,現在,你隻要核對網站位址和你現在登入的網站A是不是一個,如果是一個的話,那麼證書裡的這份公鑰就是A網站的

但實際情況還在此基礎上做了兩次改進

  1. 對于客戶來說,去第三方機構申請證書未免太繁瑣了,而且這個成本什麼的。。。而其實用戶端可以不用證書的,因為可以用使用者名和密碼來校驗身份
    1. A是伺服器,B是客戶
    2. B要登入A網站,B先擷取A的證書(不管證書從哪裡來的,它都能用你有的第三方公鑰解密來分辨)
    3. 然後B對A的證書用第三方公鑰進行解密(你事先會有一個清單,是确信的一些第三方公鑰),得到A的公鑰(而且經過驗證這确實是A的)
    4. 然後B用A的公鑰對自己要發送的【使用者名和密碼和自己的公鑰】進行一次加密,把這密文發送給A
    5. A獲得資訊之後直接用自己的私鑰解密,解密的内容中有 使用者名、密碼、使用者的公鑰
    6. 然後A隻要驗證使用者名和密碼就能知道使用者的身份,然後确認這個公鑰是這個使用者的
    7. 接下來A發送資料就可以放心使用這個公鑰進行加密了
  2. 又因為非對稱加密非常消耗計算資源,是以用戶端幹脆不用非對稱加密,然後隻要建立好了SSL連接配接,雙方安全地擁有了一把對稱加密的鑰匙之後,就都使用對稱加密互相傳遞資料
    1. A有A證書,有A公鑰和A私鑰,B開始什麼都沒有,隻持有第三方公鑰(後來生成了一個對稱密鑰)
    2. B要登入A網站,B先擷取A的證書
    3. 然後B對A的證書用第三方公鑰進行解密,得到A的公鑰(而且經過驗證這确實是A的)
    4. 然後B用A的公鑰對自己要發送的【使用者名和密碼和自己臨時生成的一個對稱密鑰】進行加密,再把加密後的資訊發送給A(外人沒有A的私鑰,是以這裡傳遞對稱密鑰非常安全)
    5. A獲得資訊之後直接用自己的私鑰解密,解密的内容中有 使用者名、密碼、對稱密鑰
    6. 然後A隻要驗證使用者名和密碼就能知道使用者的身份,然後确認這個對稱密鑰是這個使用者的
    7. 之後隻要這個SSL連接配接沒有關閉,後續的所有資料,無論是用戶端發出的還是伺服器發出的,均會使用這個對稱密鑰加密
    8. (這裡使用對稱密鑰的安全性也是有保障的,對稱加密算法中,依賴的是密鑰的保密性,隻要密鑰沒有被洩露,對稱加密的結果被截獲也沒有什麼意義。而密鑰是用公鑰加密的,隻能由伺服器解開)

雖然看起來上面這種方式已經讓https非常安全了,但其實還是有些問題的:

  1. 假如你要通路網站A,那麼一共有4種情況:
    1. 你要通路網站A,然後通路了網站A,網站A發送了一個網站A的證書給你
    2. 你要通路網站A,然後通路了網站A,網站A發送了一個網站B的證書給你
    3. 你要通路網站A,但是通路了類似釣魚網站B,網站B發送了一個網站B的證書給你(網站B神通廣大搞到一個證書)
    4. 你要通路網站A,但是通路了類似釣魚網站B,網站B自己沒有申請證書,隻好發送一個網站A的證書給你
  2. 來分析一下:
    1. 第一種情況完全沒有問題
    2. 第二種情況,發生的機率很小,而且馬上就會報錯,不會有上面問題
    3. (從這裡開始你要注意一下吊詭的地方,這兩種情況有釣魚網站B加入,危險慢慢降臨)
    4. 第四種情況,網頁會報錯,而且你确實是上了釣魚網站,看起來這個https起到作用了,它阻止了你浏覽釣魚網站,阻止了你給他們發送自己的資訊。但其實這種情況下,你不一定有危險,為什麼呢,因為釣魚網站發給你的證書是網站A的證書,當你向這個網站的伺服器發送資訊的時候是你用了網站A的證書裡的公鑰加密了你的使用者資訊,然後發送給釣魚網站B,釣魚網站B雖然劫持了你發送來的資訊,但是它并不是A網站,它沒有私鑰來對你的資訊解密,這樣的話你的資訊釣魚網站并不能擷取到(但其實這個時候我也不清楚釣魚網站會不會有其他手段,是以這種情況也可能因為其他原因而比較危險)
    5. 反倒是第三種情況,這時候你上了釣魚網站,但是網頁并不會報錯,因為網址和證書中的一緻,https并不會阻止你上這個釣魚網站,而且由于你用了釣魚網站的公鑰對你的資訊進行加密,是以釣魚網站可以對你的資訊進行解密并擷取,這時候才是真正危險的時候
  3. 總結就是,使用https并不能完全保證你的上網安全,其中主要是你的原因,其次https也有部分原因,具體在使用https的時候如何避免洩露資訊呢:
    1. 所有https告訴你這個證書被冒用時,你一定要好好檢查你的浏覽器位址框,不要上錯了網站
    2. 即使https沒有告訴你證書被冒用,你也更加要好好檢查你的浏覽器位址框,不要上錯了網站,這時候https并不能保護你
    3. 當https告訴你這個證書的頒發商不靠譜,你就也要小心,這可能有問題,也可能沒問題,但是你最好還是不要上
    4. 希望https的頒發機構們工作細緻,不要給釣魚網站頒發證書