這篇文章跟大家討論一個比較有意思的問題:怎麼破解https?大家都知道,現在幾乎整個網際網路都採用了https,不是https的網站某些瀏覽器還會給出警告。面試中也經常問到https,本文會深入https原理,一直講到https破解思路。
HTTPS
要想破解https,必須先知道https原理,下面我們先來講講https原理。
公私鑰
https的公私鑰經常在面試中出現,各種面經也會給出答案:https有兩個祕鑰,公鑰和私鑰,網站自己持有私鑰,使用者持有公鑰,網站用自己的私鑰加密資料發給使用者,使用者用公鑰解密資料。使用者要發資訊就反過來,使用者用公鑰加密資料,網站用私鑰解密資料。這種加密和解密使用不同祕鑰的加密演算法叫做非對稱加密。這個流程有點繞,下面舉例來說明下,假設網站A啟用了https,小明要來訪問這個網站了(以下例子僅為講解公私鑰用途,並非https真實流程,真實流程是“HTTPS握手流程”一節):
- 網站A啟用https,自然有一對祕鑰,私鑰和公鑰,私鑰他自己藏起來了,公鑰任何訪問使用者都可以拿到
- 小明訪問網站A,拿到了A的公鑰
- 小明要給網站A發訊息就用公鑰給資訊加密,然後發給網站A
- 網站A拿到密文後,用自己的私鑰解密得到訊息內容
- 網站A要給小明回信,用自己的私鑰加密資訊,傳送給小明
- 小明拿到密文後,用自己手上的公鑰解密資訊
通過上面的流程我們可以看出,由於公鑰是公開的,所以網站私鑰加密的資訊其實所有使用者都可以解開。在這一個階段,保護的其實是使用者發給伺服器的資料,因為使用者加密的資料必須要伺服器的私鑰才能解開。這裡大家想一個有意思的問題:既然所有使用者都能拿到公鑰,那是不是小明加密的資訊,小紅也能解開呢,因為小紅也有公鑰啊?如果小紅也能解開,那小紅只要截獲了小明的流量,不就知道內容了嗎?這個問題簡化一下就是,公鑰加密的資訊用同一個公鑰能解開嗎?答案是不能!要知道這個原因必須要知道RSA演算法,我們後面會講,先一步步來。
數字證書
前面小明訪問網站A的流程是有隱患,可以被攻擊的。假設小紅是個中間人黑客,現在想攻擊小明,她偷偷在小明電腦上做了手腳,將網站A的公鑰換成了自己的:
- 小明訪問網站A,網站A給小明傳送公鑰,但是這一步被小紅攻擊了
- 小紅劫持了小明的流量,將網站A發過來的公鑰替換成了自己的公鑰
- 小明拿到了錯誤的公鑰,用這個公鑰加密自己的資訊,這個資訊可能包含他的使用者名稱,密碼等敏感資訊
- 小明將加密資訊傳送給網站A,這個流量被小紅截獲
- 因為密文是用小紅的公鑰加密的,小紅用對應的私鑰解密,得到小明的密碼,攻擊完成
可以看到僅僅是公私鑰還是不能應對中間人的流量劫持,傳輸過程中資訊被截獲仍然會被破解。這個攻擊能成功的關鍵點就是小明拿到了錯誤的公鑰,所以需要一種機制來保證小明拿到正確的網站A公鑰,這個機制就是數字證書。數字證書說開了很簡單,他裡面核心東西就一個,就是網站A的公鑰。網站A將自己的公鑰放到數字證書裡面傳送給小明,小明一看,這個公鑰是證書認證的,可信,就用這個了。即使小紅替換了公鑰,因為小紅的公鑰沒有證書認證,所以小明也可以識別出這個假冒貨。
那數字證書的安全性又是怎麼保證的呢,小紅再偽造一個數字證書不就行了嗎?這就要說到CA(CertificateAuthority)了,CA是頒發數字證書的機構,CA有自己的公私鑰。CA用自己的私鑰加密一個資訊,這個資訊就是網站A的公鑰,然後傳送給使用者,使用者拿到這個資訊用CA的公鑰解密,就拿到了正確的網站A的公鑰了。所以,數字證書其實就是CA私鑰加密過的網站公鑰。小紅沒有CA的私鑰,她就偽造不出來網站的數字證書了,也就沒法替換小明拿到的公鑰了。所以,數字證書其實保證了網站公鑰的正確性,CA保證了數字證書的安全性。
既然CA保證了數字證書的安全性,那誰來保證CA的安全性呢?假設有個東西X保證了CA的安全性,那誰來保證X的安全性呢?感覺這個信任鏈條可以無窮盡呢。。。現實中,CA的安全級別非常高,他的安全不僅僅有技術手段,還有法律,物理措施等。反過來說,回到本文的主題,破解https,到這裡我們其實有了第一個思路:黑掉CA!你就可以將它名下所有證書的公鑰都替換成自己的,解密使用他證書的所有網站。
評論區有朋友提到,Charles可以解密https,這個原理不就跟小紅攻擊小明的原理一樣嘛。Charles解密https的前提是你要安裝他的證書,安裝了他的證書,你其實就相當於信任了Charles這個假的CA。攻擊流程將前面的小紅換成Charles就行了。
會話祕鑰
公私鑰的加密解密確實很安全,但是他的速度很慢,如果每條資訊都這麼操作,會影響整個交流效率,所以當我們跟https建立連線後,通過公私鑰交換的資訊其實只有一個:會話祕鑰。會話祕鑰不是非對稱加密,而是對稱加密。對稱加密在某些影視作品中很常見:某主人公得到一個藏寶圖,苦於藏寶圖是密碼寫的,看不懂,百般無奈下,想起祖傳的某某書籍,拿到一對照,那本書剛好可以解密藏寶圖密碼。那這本書其實就是密碼本,二戰中很多資訊加密就用的密碼本的方式,通過截獲密碼本獲取對方軍事情報的事情也不少。加密解密都用密碼本,其實就是用了同一個祕鑰,這就是對稱加密。用計算機領域的話來說,這個密碼本不就是一個hash函式嘛,這個函式將一個字元對映成另外一個字元。舉個例子,我們加密的hash函式就是將字元後移三位,a -> d, b -> e 這種,那"hello"就變成了:
h -> ke -> h
l -> o
l -> o
o -> r
"hello"就變成了"khoor",那攻擊者只要知道了你這個演算法,再反算回來,前移三位就解密了。所以對稱加密相對來說並不安全,但是,如果我能保證他的密碼本(也就是祕鑰)是安全的,對稱加密也可以是安全的。那對稱加密的祕鑰怎麼保證安全呢?用公私鑰再加一次密啊!所以https連線後,公私鑰交換的資訊只有一個,那就是對稱加密祕鑰,也就是會話祕鑰。對稱加密的演算法就是一個hash函式,加密解密相對更快,這種設計是從效率的角度考慮的。
數字簽名
數字簽名其實很簡單,是用來保障資訊的完整性和正確性的:
- 小明先將明文資訊用摘要演算法生成一個摘要,這個演算法類似於MD5,SHA-1,SHA-2,就是一個不能反解的hash函式
- 小明用公鑰對這個摘要進行加密
- 小明將這個簽名附加在內容後面一起發給服務端
- 服務端接收到簽名後,用私鑰解密出摘要
- 服務端對內容進行同樣的摘要演算法,得出摘要
- 服務端算出的摘要如果跟簽名裡面的一樣,則內容完整,沒有被篡改
HTTPS握手流程
前面幾個知識點其實已經把https的關鍵點都講了,下面我們來總結下https握手流程:
- 小明向網站A發起請求
- 網站A將CA數字證書返回給客戶端,證書裡面有網站A的公鑰
- 小明通過自己電腦內建的CA公鑰解密證書,拿到網站A的公鑰(CA公鑰內建在瀏覽器中)
- 小明生成隨機的對稱祕鑰,也就是會話祕鑰。會話祕鑰一定要客戶端生成,因為前面說了,這裡公私鑰只能保證客戶端發給網站資訊的安全,公鑰加密的資訊只有私鑰才能解開,私鑰網站藏起來了,所以其他人拿到資訊也解不開。但是如果網站生成會話祕鑰,用他的私鑰加密,那所有人都有公鑰,所有人都能解開了。
- 小明將會話祕鑰通過網站A的公鑰加密,傳送給網站A
- 接下來網站A和小明使用會話祕鑰進行HTTP通訊
RSA演算法
前面我們提到過公鑰加密的資訊用同一個公鑰也解不開,只能用私鑰解密,這其實就是非對稱加密的核心機密,下面我們來講講這個機密是怎麼做到的,這其實就是RSA演算法。RSA演算法計算流程如下:
- 隨機選取兩個質數p和q
- 計算 n = pq
- 計算 φ(n) = (p-1)(q-1)
- 找一個與φ(n)互質的小奇數e,互質是指兩個數的公約數只有1
- 對模φ(n),計算e的乘法逆元d,即找到一個d,使下列等式成立:(e*d) mod φ(n) = 1
- 得到公鑰:(e, n),私鑰: (d, n)
- 加密過程:c = (m^e) mod n, (c為加密後的密文,m為原文)
- 解密過程:m = (c^d) mod n
第七步說明下,m的e次方,m就是我們傳送的原文,可以是文字,json,圖片,雖然形式多樣,但是在計算機裡面都是二進位制01,所以可以轉換成數字求次方。下面我們找兩個數來試一下這個演算法:
- 隨便選兩個質數23和61
- 計算 n = 23 * 61 = 1403
- 計算 φ(n) = (23-1) * (61-1) = 22 * 60 = 1320
- 找一個與φ(n)互質的小奇數e,我們選7
- 計算乘法逆元d,我這裡算好的是 d =943。對乘法逆元感興趣的朋友可以網上搜搜怎麼算,因為不是本文主題,我就不展開了。
- 得到公鑰(7, 1403),私鑰(943, 1403)
- 我們用公鑰隨便加密一個5試試,加密 c = (m^e) mod n = (5^7) % 1403 = 78125 % 1403 = 960
- 私鑰解密: m = (c^d) mod n = (960^943) % 1403 = 5,(960^943)這個數字超級大,一般計算器算不出來,JS計算更不行,我是用這個網站算的:https://defuse.ca/big-number-...
- 再試試私鑰加密:c = (m^d) mod n = (5^943) % 1403 = 283
- 公鑰解密: m = (c^e) mod n = (283 ^ 7) % 1403 = 5
知道了演算法,我們就可以來解答前面的那個問題了,為什麼公鑰自己加密的資料自己還解不出來?注意看加密演算法(m^e) mod n
這是個模運算啊,模運算是不能反解的。比如5對4取模,5%4=1,但是反過來,知道x%4=1,求x。這個x可以有無限個,5,9,13,17。。。所以即使你有公鑰(e,n),和密文c,你也不知道(m^e)到底取哪個值,是反解不出來的,這就是非對稱加密的核心機密,私鑰加密同理,自己加密的自己也反解不出來。
RSA破解思路
所謂破解RSA,其實就是通過公開的資訊推測出他藏起來的資訊,具體來說就是已知公鑰(e, n)求私鑰(d,n),也就是求d。要求d,其實就是反解(e*d) mod φ(n) = 1
,要反解這個式子,就必須知道φ(n),因為φ(n) = (p-1)(q-1),所以必須知道p和q。我們知道n=pq,而且n是已知的,所以還是有可能知道p和q的。所以破解RSA其實就是一句話:n是已知的,將n拆成兩個質數之積就行了。說起來簡單,做起來非常難!因為實際使用時,n非常大,現在好多地方用的n都是2048 bits甚至4096 bits,這個數字轉換成十進位制也有幾百位上千位長,做個對比,JS整數最多支援53 bits。。。所以現實中有兩條路來破解RSA:
- 找出一個演算法,能夠高效的將大數n拆分成兩個質數。可惜目前數學界也還沒找到這個演算法。
- 沒有好辦法就用笨辦法,窮舉,從2開始遍歷p, q,直到他們的乘積為n為止。據說有人花了5個月時間算出了一個512 bits的n,然後人家早就換了祕鑰,RSA還升級到了1024 bits...
總結
- HTTPS其實就是HTTP+RSA+數字證書+會話祕鑰
- RSA實現了非對稱加密,可以讓公鑰任意分發,私鑰即使丟失了,也可以迅速換一對公私鑰。解決了對稱加密密碼本的漏洞。
- 數字證書保證了分發的公鑰不能被篡改。
- CA保證了數字證書的安全性。
- CA的安全性由誰保證是個玄學
- 會話祕鑰是對稱加密,目的是為了加快加密解密速度
RSA演算法精髓:
- 加密使用模運算,完全不能反解
- n取一個超大數,超出了數學界理論極限和計算機的工業極限
破解HTTPS三條路:
- 黑掉CA,將它名下證書的公鑰都換成你的,方法勿論。。。
- 數學之神附體,找到高效大數分解演算法,分分鐘算出p,q
- 圖靈附體,研發出超快的量子計算機,秒秒鐘算出p,q
- 自己網站沒開https的趕緊回去開,記得找個靠譜的CA買證書
文章的最後,感謝你花費寶貴的時間閱讀本文,如果本文給了你一點點幫助或者啟發,請不要吝嗇你的贊和GitHub小星星,你的支援是作者持續創作的動力。
作者博文GitHub專案地址: https://github.com/dennis-jiang/Front-End-Knowledges
我也搞了一個公眾號[進擊的大前端],不打廣告,不寫水文,只發高質量原創,歡迎關注: