
這個問題是一個讀者面試時遇到的一個問題,準備過面試的人應該都記得,非對稱加密與對稱加密的區(qū)別之一就是非對稱加密的速度慢,但是我們做業(yè)務開發(fā)的時候通常都是直接調(diào)用算法,對其原因并沒有過多深究,因此如果有面試官問到了這個問題,的確會讓人措手不及。正好借著這篇文章來說一說。
對稱加密與非對稱加密
首先我們先來說一下到底什么是對稱加密,什么是非對稱加密,這一節(jié)主要是用一些例子來介紹一下對稱加密和非對稱加密是什么,如果你已經(jīng)了解了,可以跳過本節(jié)。
對稱加密
高中生小明和小紅是一對“地下情侶”,可偏偏他們一個坐在教室前,一個坐在教室后,所以晚自習的時候也只能通過紙條傳情。這時一個很尷尬的事情就出現(xiàn)了,由于無法直接將紙條交給對方,因此紙條必須要經(jīng)過多個人的傳遞,可總有一兩個八卦的人喜歡看紙條里寫的什么。為了避免被班主任抓包以及被同學們窺視,他們兩約定,用現(xiàn)代漢語詞典當作“密碼本”,以后傳紙條時,紙條上的內(nèi)容是要寫的字在詞典里的頁碼及順序,這樣即使紙條被別人看了,不知道密碼本是什么的人也就不會得知紙條里的真正內(nèi)容了。
在上述的例子中,紙條是承載信息的載體,紙條里的內(nèi)容是信息,漢語詞典是密鑰,將文字映射到漢語詞典的頁碼和順序是加密方式(算法)。
類似于上面這種,在加密和解密時使用相同的密鑰,或是使用兩個可以簡單地相互推算的密鑰的加密方式就是對稱密鑰加密(Symmetric-key algorithm),簡稱對稱加密。常見的對稱加密算法有:AES、DES、3DES
所以你可以將對稱加密簡單理解為:一方通過密鑰將信息加密后,把密文傳給另一方,另一方通過這個相同的密鑰將密文解密,轉(zhuǎn)換成可以理解的明文。他們之間的關系如下圖所示(這里借用一下@寒食君的圖):
弊端
這種加密方式雖然簡單,但是其弊端也是非常明顯的。在上面的例子中,如果傳遞紙條的人知道了他們這種加密方式,那就同樣可以通過查閱漢語詞典解析出他們的紙條內(nèi)容。如下圖所示。這樣為什么眾多抗戰(zhàn)片中會出現(xiàn)瘋狂搶奪密碼本這一情節(jié)也就很好理解了。
非對稱加密
再舉一個生活中非常常見的例子。小區(qū)里的小伙伴們經(jīng)常可以在自家的郵箱里收到信件,比如你的錄取通知書,當然更多可能是廣告。不過,雖然說所有人都可以往里面扔郵件,但是只有你可以打開這個郵箱查看這個郵件。
上面這個過程就是一個很形象的非對稱加密。
非對稱加密不同于對稱加密,它有一對秘鑰,一個稱為公鑰(publicKey) ,另一個稱為私鑰(privateKey),并且*只知道公鑰是無法推算出私鑰。*就和上面的例子中只知道郵箱位置卻并不能打開郵箱是一個道理。常見的非對稱加密算法有:RSA、DSA、ECC
另外,這種算法還有一個特別神奇的功能,那就是通過公鑰加密的內(nèi)容,只有私鑰才可以解開,而通過私鑰加密的內(nèi)容,只有公鑰才可以解開。
公鑰/私鑰的用法
第一種用法:公鑰加密,私鑰解密。---用于加解密
第二種用法:私鑰簽名,公鑰驗簽。---用于簽名
其實很容易理解:
既然是加密,那肯定是不希望別人知道我的消息,所以只有我才能解密,所以可得出公鑰負責加密,私鑰負責解密;
既然是簽名,那肯定是不希望有人冒充我發(fā)消息,只有我才能發(fā)布這個簽名,所以可得出私鑰負責簽名,公鑰負責驗證。
這里提一點:簽名 ≠ 加密,通俗點說加密就是你哪怕看到了不該看到的東西,也理解不了。而簽名就是你做了任何事,都抵賴不了。
為什么非對稱加密比對稱加密慢?
介紹了這兩種加密方式后,我們終于可以回到本篇文章的開頭了,為什么非對稱加密會比對稱加密慢?
這是因為對稱加密主要的運算是位運算,速度非常快,如果使用硬件計算,速度會更快。以 AES 算法為例,如下圖所示,其運算本質(zhì)上來說就是位移和替換。
但是非對稱加密計算一般都比較復雜,比如 RSA,它里面涉及到大數(shù)乘法、大數(shù)模等等運算。其加解密可以用下面的公式來表示:

我們知道,冪運算的本質(zhì)是乘法,乘法的基礎單位是加法,也就是我們最常見的整數(shù)加。學過數(shù)字邏輯電路的同學想必都知道,在電路上實現(xiàn)“加法”比異或(XOR)要麻煩的多,況且后面還有一個模運算。因此非對稱加密的速度自然而然是比不過對稱加密的。
當然,我想另外還有一個原因是,AES 中的許多中間計算過程是可以事先計算好的。加密數(shù)據(jù)時許多中間過程可以直接查表,而不需要實時地計算。
通常情況下,非對稱加密(如 RSA)的解密速度會比加密速度更慢,詳情可參考Why is RSA decryption slow?
時空性
這里另外提一點,我們在學習算法的時候,一定聽過時間復雜度和空間復雜度這兩個名詞。魚和熊掌不可兼得,通常情況下,一個算法如果運行比較快,那么空間消耗相對來說就會高一些,反之亦然。因此才會有拿空間換時間的說法。
從上一節(jié)我們可以知道,非對稱加密運行起來通常比對稱加密慢,那么這時就有一個問題了,對于密鑰的存儲情況也是這樣嗎?非對稱加密對于密鑰的存儲會比對稱加密的密鑰存儲少嗎?
答案是的確如此,在對稱加密中,當信息量大的時候,要求密鑰量也要足夠大,需要每兩個人之間都有一個密鑰,也就是對于 n 個人來說,一共需要 n(n-1)/2 個密鑰才能確保兩兩之間對話不被其他人知道。
而在非對稱加密中,每個人都有公鑰和私鑰,對于 n 個人來說,一共要 2n 個密鑰,就能保證兩兩之間對話不被其他人知道。
什么?你問我這個公式怎么來的?數(shù)學歸納法了解一下?
這么看,非對稱加密雖然效率低下,但是存儲成本低且相對安全,這也就解釋了為什么非對稱加密應用如此廣泛了。
HTTPS
既然無法做到既安全又快速的加解密,那我們在實際使用時只能盡量達到一個動態(tài)的平衡。
因此我們在項目中通常會采用如下這種將兩種加密算法結(jié)合在一起的使用方式:
- 首先隨機生成單次請求加密密鑰(clientAesKey,長度為 16 位,可以用 26 個字母和數(shù)字組成)
- RSA 負責加密一個字符串(clientAesKey)、
- AES 負責用這個字符串(clientAesKey)、明文加密為一個密文。
- 解密時首先要用 RSA 獲取這個字符串(clientAesKey)、然后再用 AES 解密密文。
之所以本節(jié)的標題是 HTTPS,是因為在 HTTPS 中就使用了上述這種加解密的方式。關于 HTTPS 的詳解,可以參考我的好朋友寒食君的這篇《談戀愛也要懂 HTTPS》。
現(xiàn)在如果有面試官問你,在 https 中采用了哪種加密方式,我想你應該知道答案了吧。