這個問題是一個讀者面試時遇到的一個問題,準備過面試的人應(yīng)該都記得罢维,非對稱加密與對稱加密的區(qū)別之一就是非對稱加密的速度慢淹仑,但是我們做業(yè)務(wù)開發(fā)的時候通常都是直接調(diào)用算法,對其原因并沒有過多深究肺孵,因此如果有面試官問到了這個問題匀借,的確會讓人措手不及。正好借著這篇文章來說一說平窘。
對稱加密與非對稱加密
首先我們先來說一下到底什么是對稱加密吓肋,什么是非對稱加密,這一節(jié)主要是用一些例子來介紹一下對稱加密和非對稱加密是什么瑰艘,如果你已經(jīng)了解了是鬼,可以跳過本節(jié)。
對稱加密
高中生小明和小紅是一對“地下情侶”紫新,可偏偏他們一個坐在教室前均蜜,一個坐在教室后,所以晚自習(xí)的時候也只能通過紙條傳情芒率。這時一個很尷尬的事情就出現(xiàn)了囤耳,由于無法直接將紙條交給對方,因此紙條必須要經(jīng)過多個人的傳遞偶芍,可總有一兩個八卦的人喜歡看紙條里寫的什么充择。為了避免被班主任抓包以及被同學(xué)們窺視,他們兩約定匪蟀,用現(xiàn)代漢語詞典當(dāng)作“密碼本”椎麦,以后傳紙條時,紙條上的內(nèi)容是要寫的字在詞典里的頁碼及順序材彪,這樣即使紙條被別人看了观挎,不知道密碼本是什么的人也就不會得知紙條里的真正內(nèi)容了撒桨。
在上述的例子中,紙條是承載信息的載體键兜,紙條里的內(nèi)容是信息凤类,漢語詞典是密鑰,將文字映射到漢語詞典的頁碼和順序是加密方式(算法)普气。
類似于上面這種谜疤,在加密和解密時使用相同的密鑰,或是使用兩個可以簡單地相互推算的密鑰的加密方式就是對稱密鑰加密(Symmetric-key algorithm)现诀,簡稱對稱加密夷磕。常見的對稱加密算法有:AES、DES仔沿、3DES
所以你可以將對稱加密簡單理解為:一方通過密鑰將信息加密后坐桩,把密文傳給另一方,另一方通過這個相同的密鑰將密文解密封锉,轉(zhuǎn)換成可以理解的明文绵跷。他們之間的關(guān)系如下圖所示(這里借用一下@寒食君的圖):
![](https://upload-images.jianshu.io/upload_images/5666077-0a25984c8f1bb604.png&originHeight=359&originWidth=1080&size=262520&status=done&style=none&width=716?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
弊端
這種加密方式雖然簡單,但是其弊端也是非常明顯的成福。在上面的例子中碾局,如果傳遞紙條的人知道了他們這種加密方式,那就同樣可以通過查閱漢語詞典解析出他們的紙條內(nèi)容奴艾。如下圖所示净当。這樣為什么眾多抗戰(zhàn)片中會出現(xiàn)瘋狂搶奪密碼本這一情節(jié)也就很好理解了。
![](https://upload-images.jianshu.io/upload_images/5666077-5d78e9d695116d66.png&originHeight=292&originWidth=1080&size=253269&status=done&style=none&width=742?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
非對稱加密
再舉一個生活中非常常見的例子蕴潦。小區(qū)里的小伙伴們經(jīng)诚裉洌可以在自家的郵箱里收到信件,比如你的錄取通知書潭苞,當(dāng)然更多可能是廣告忽冻。不過,雖然說所有人都可以往里面扔郵件萄传,但是只有你可以打開這個郵箱查看這個郵件甚颂。
上面這個過程就是一個很形象的非對稱加密蜜猾。
![](https://upload-images.jianshu.io/upload_images/5666077-89e102c5148f83df.png&originHeight=946&originWidth=1576&size=145455&status=done&style=none&width=788?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
非對稱加密不同于對稱加密秀菱,它有一對秘鑰,一個稱為公鑰(publicKey) 蹭睡,另一個稱為私鑰(privateKey)衍菱,并且*只知道公鑰是無法推算出私鑰。*就和上面的例子中只知道郵箱位置卻并不能打開郵箱是一個道理肩豁。常見的非對稱加密算法有:RSA脊串、DSA辫呻、ECC
另外,這種算法還有一個特別神奇的功能琼锋,那就是通過公鑰加密的內(nèi)容放闺,只有私鑰才可以解開,而通過私鑰加密的內(nèi)容缕坎,只有公鑰才可以解開怖侦。
公鑰/私鑰的用法
第一種用法:公鑰加密,私鑰解密谜叹。---用于加解密
第二種用法:私鑰簽名匾寝,公鑰驗簽。---用于簽名
其實很容易理解:
既然是加密荷腊,那肯定是不希望別人知道我的消息艳悔,所以只有我才能解密,所以可得出公鑰負責(zé)加密女仰,私鑰負責(zé)解密猜年;
既然是簽名,那肯定是不希望有人冒充我發(fā)消息疾忍,只有我才能發(fā)布這個簽名码倦,所以可得出私鑰負責(zé)簽名,公鑰負責(zé)驗證锭碳。
這里提一點:簽名 ≠ 加密袁稽,通俗點說加密就是你哪怕看到了不該看到的東西,也理解不了擒抛。而簽名就是你做了任何事推汽,都抵賴不了。
為什么非對稱加密比對稱加密慢歧沪?
介紹了這兩種加密方式后歹撒,我們終于可以回到本篇文章的開頭了,為什么非對稱加密會比對稱加密慢诊胞?
這是因為對稱加密主要的運算是位運算暖夭,速度非常快撵孤,如果使用硬件計算迈着,速度會更快。以 AES 算法為例邪码,如下圖所示裕菠,其運算本質(zhì)上來說就是位移和替換。
![](https://upload-images.jianshu.io/upload_images/5666077-7e8b569ab9ac81b3.png&originHeight=1580&originWidth=1200&size=460372&status=done&style=none&width=307?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
但是非對稱加密計算一般都比較復(fù)雜闭专,比如 RSA奴潘,它里面涉及到大數(shù)乘法旧烧、大數(shù)模等等運算。其加解密可以用下面的公式來表示:
![image.png](https://upload-images.jianshu.io/upload_images/5666077-0c85df237d3c5318.png&originHeight=106&originWidth=476&size=10211&status=done&style=none&width=238?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://upload-images.jianshu.io/upload_images/5666077-a22d41321e767110.png&originHeight=122&originWidth=460&size=10294&status=done&style=none&width=230?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
我們知道画髓,冪運算的本質(zhì)是乘法掘剪,乘法的基礎(chǔ)單位是加法,也就是我們最常見的整數(shù)加奈虾。學(xué)過數(shù)字邏輯電路的同學(xué)想必都知道杖小,在電路上實現(xiàn)“加法”比異或(XOR)要麻煩的多,況且后面還有一個模運算愚墓。因此非對稱加密的速度自然而然是比不過對稱加密的予权。
當(dāng)然,我想另外還有一個原因是浪册,AES 中的許多中間計算過程是可以事先計算好的扫腺。加密數(shù)據(jù)時許多中間過程可以直接查表,而不需要實時地計算村象。
通常情況下笆环,非對稱加密(如 RSA)的解密速度會比加密速度更慢,詳情可參考Why is RSA decryption slow?
時空性
![](https://upload-images.jianshu.io/upload_images/5666077-4b614bb03042b8b8.png&originHeight=493&originWidth=512&size=300939&status=done&style=none&width=161?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
這里另外提一點厚者,我們在學(xué)習(xí)算法的時候躁劣,一定聽過時間復(fù)雜度和空間復(fù)雜度這兩個名詞。魚和熊掌不可兼得库菲,通常情況下账忘,一個算法如果運行比較快,那么空間消耗相對來說就會高一些熙宇,反之亦然鳖擒。因此才會有拿空間換時間的說法。
從上一節(jié)我們可以知道烫止,非對稱加密運行起來通常比對稱加密慢蒋荚,那么這時就有一個問題了,對于密鑰的存儲情況也是這樣嗎馆蠕?非對稱加密對于密鑰的存儲會比對稱加密的密鑰存儲少嗎期升?
答案是的確如此,在對稱加密中互躬,當(dāng)信息量大的時候播赁,要求密鑰量也要足夠大,需要每兩個人之間都有一個密鑰吨铸,也就是對于 n 個人來說行拢,一共需要 n(n-1)/2 個密鑰才能確保兩兩之間對話不被其他人知道。
而在非對稱加密中诞吱,每個人都有公鑰和私鑰舟奠,對于 n 個人來說,一共要 2n 個密鑰房维,就能保證兩兩之間對話不被其他人知道沼瘫。
什么?你問我這個公式怎么來的咙俩?數(shù)學(xué)歸納法了解一下耿戚?
這么看,非對稱加密雖然效率低下阿趁,但是存儲成本低且相對安全膜蛔,這也就解釋了為什么非對稱加密應(yīng)用如此廣泛了。
HTTPS
既然無法做到既安全又快速的加解密脖阵,那我們在實際使用時只能盡量達到一個動態(tài)的平衡皂股。
因此我們在項目中通常會采用如下這種將兩種加密算法結(jié)合在一起的使用方式:
- 首先隨機生成單次請求加密密鑰(clientAesKey,長度為 16 位命黔,可以用 26 個字母和數(shù)字組成)
- RSA 負責(zé)加密一個字符串(clientAesKey)呜呐、
- AES 負責(zé)用這個字符串(clientAesKey)、明文加密為一個密文悍募。
- 解密時首先要用 RSA 獲取這個字符串(clientAesKey)蘑辑、然后再用 AES 解密密文。
之所以本節(jié)的標題是 HTTPS坠宴,是因為在 HTTPS 中就使用了上述這種加解密的方式洋魂。關(guān)于 HTTPS 的詳解,可以參考我的好朋友寒食君的這篇《談戀愛也要懂 HTTPS》喜鼓。
現(xiàn)在如果有面試官問你忧设,在 https 中采用了哪種加密方式,我想你應(yīng)該知道答案了吧颠通。
![](https://upload-images.jianshu.io/upload_images/5666077-b33e648ef7313e2f.png&originHeight=553&originWidth=851&size=1103302&status=done&style=none&width=278?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)