讓你的網(wǎng)站免費(fèi)開啟 HTTPS -- 從對稱加密到非對稱加密

前言

本來覺得也就是一個普通的博客網(wǎng)站,用不用 HTTPS 似乎也沒什么大不了。但是在網(wǎng)絡(luò)上各種信息的狂轟亂炸下,還是決定把這個問題解決一下。在這件事之前筆者還遇到了一個很蛋疼的問題,那就是我被勒索了?。?!事情是這樣的,某一個美好的周六的上午,突然收到一封來自俄羅斯的郵件,怎么會有老毛子發(fā)郵件給我?帶著疑惑打開郵件,然后發(fā)現(xiàn),特么的,告訴我他已經(jīng)完全控制了我的設(shè)備(然而事實(shí)上我并沒有發(fā)現(xiàn)任何設(shè)備的異常),要我轉(zhuǎn) 2000 刀到他的比特幣賬戶上面,否則就巴拉巴拉。好吧,你隨意,我電腦不值 2000 刀,我的信息也不值。不過到最后什么動靜也沒有,看起來就是簡單的發(fā)郵件忽悠我???雖然到最后我也沒有什么損失,但是這件事深切的讓我感受到信息安全的重要性。

廢話不多說,進(jìn)入正題~

本文首發(fā)于心安-XinAnzzZ 的個人博客,轉(zhuǎn)載請注明出處~

對稱加密 vs 非對稱加密

先來看兩個基礎(chǔ)的概念,這是本文的基礎(chǔ),希望讀者仔細(xì)看一下這一塊。

  • 對稱加密

    對稱加密就是通訊雙方持有相同的密鑰(和加密方式),然后 A 方通過密鑰將明文進(jìn)行加密得到密文,B 端使用相同的密鑰將密文進(jìn)行解密,得到明文。

對稱加密

優(yōu)點(diǎn):對稱加密的優(yōu)點(diǎn)是加密速度非???;

缺點(diǎn):由于通訊雙方需要使用相同的密鑰進(jìn)行通訊,那么在通訊之前通訊雙方需要約定密鑰,在互聯(lián)網(wǎng)中,雙方是不認(rèn)識的,如何安全的約定密鑰是一個很難解決的問題。并且在約定密鑰的過程中密鑰一旦被泄露,那么之后通訊中的信息就可能會被別人獲取。

所以說,如何安全的約定密鑰是對稱加密的一個關(guān)鍵點(diǎn)。

  • 非對稱加密

    非對稱加密是需要生成一對密鑰,分別叫做公鑰和私鑰。顧名思義,私鑰自己擁有,而公鑰是公開的。特點(diǎn):

    • 使用公鑰加密的密文只有對應(yīng)的私鑰才能解密(就連公鑰自己也無法解密自己加密的信息);
    • 相反的,使用私鑰加密的信息,也只有對應(yīng)的公鑰才能解密(同樣的,私鑰也不能解密自己加密的信息)。
非對稱加密

從上面的公式可以看到,明文和密文之間是兩個單箭頭,這里就和對稱加密有所區(qū)別了。對稱加密是只有擁有密鑰,明文可以變成密文,密文也可以變成明文。而非對稱加密是明文通過公鑰加密之后只有私鑰可以解密,通過私鑰加密只能通過公鑰進(jìn)行解密。

我們先看左邊這個公式,明文使用公鑰進(jìn)行加密,然后只能使用私鑰解密,這有什么用呢?試想一下,如果我把我的公鑰給別人,然后讓別人用公鑰加密信息發(fā)送給我,由于只有我自己擁有私鑰,所以這個信息是完全安全的。而對比對稱加密,我要把對稱加密的密鑰給別人,然后讓別人使用這個密鑰加密信息然后發(fā)送給我,看起來也蠻安全的。

這兩者都要把密碼給別人,但是區(qū)別就是,如果使用非對稱加密時,我完全不擔(dān)心在給別人公鑰時被暴露公鑰,因?yàn)榧词褂衅渌双@取到了我的公鑰,也沒什么用。但是如果是對稱加密的密鑰就不行了,完全不能暴露。

這就說明了一個問題:使用公鑰加密的的信息只有私鑰能夠解密,而私鑰只有密鑰對的擁有者才擁有,也就意味著只有密鑰對的擁有者才能解密使用公鑰加密的信息。

我們再看一下第二個公式,明文使用私鑰進(jìn)行加密,然后只能用公鑰解密。這下讀者可能就疑惑了,誒,那不出大事了嗎?上面不是說公鑰是公開的嗎,那你使用私鑰加密的內(nèi)容不是人人可見?

誒,對了,這就對了。因?yàn)橛盟借€加密信息不是為了信息保密,只是為了證明身份。

試想一下,如果我用私鑰加密,然后別人拿著我的公鑰進(jìn)行解密,哎喲,竟然解開了,那說明什么?你想啊,既然能夠用我的公鑰解密,那是不是意味著這個信息是我的私鑰進(jìn)行加密的?那誰擁有我的私鑰呢?當(dāng)然是我本人了。那是不是就說明了,這個信息是來自于我?因?yàn)閯e人沒有我的私鑰,所以別人無法偽造。

這又說明了一個問題:如果使用公鑰能夠解密私鑰加密后信息(這里公鑰私鑰是配對的),那就意味著這個信息確實(shí)是密鑰對擁有者發(fā)送的信息。

讀到這兒不知道讀者有沒有覺得這個算法很牛逼,反正筆者是覺得算法的發(fā)明者真他娘的是個天才。

image

那你說這個算法這么牛逼,就沒有缺點(diǎn)嗎?有,速度慢,特別消耗 cpu,加密速度和對稱加密不是一個量級的。

這么牛逼的算法,原理是啥呢?筆者才疏學(xué)淺就不再繼續(xù)展開了,感興趣的小伙伴可以看一下阮一峰老師寫的RSA算法原理(一)RSA算法原理(二)這兩篇文章,寫的很詳細(xì)。

敲黑板,劃重點(diǎn)了?。?!

總結(jié)一下非對稱加密的作用:

  1. 使用公鑰加密只有私鑰才能解密,可以用來信息加密安全傳輸。
  2. 使用私鑰加密只有公鑰才能解密,可以用來身份認(rèn)證。只要你能確定這個公鑰是我的公鑰,那么不管這個信息來自于哪里,只要能解密,就意味著是我發(fā)出的。
  • 對比

    通過上面的介紹,可以發(fā)現(xiàn):
    1、對稱加密,速度快,但是安全性不夠高,如果能解決公鑰的安全性,那就完美了。
    2、非對稱加密,安全性非常高,但是性能較差,不適合大規(guī)模使用。

    所以有以下思路,那就是先使用非對稱加密來傳遞用于對稱加密的公鑰,然后后續(xù)全部使用對稱加密進(jìn)行通訊,這樣就不僅能夠保證足夠的安全性,同時加密的開銷也會不會很大。

使用密文進(jìn)行傳輸

HTTP 協(xié)議是明文傳輸,容易被偷看和篡改,而 HTTPS 使用加密傳輸,所以更加安全。HTTPS 是 HTTP 協(xié)議再加上一層 SSL/TSL 安全協(xié)議來保證安全的,除了安全,HTTPS 協(xié)議的網(wǎng)站也能夠提升在搜索引擎中的排名(SEO),簡單來說就是更容易在搜索引擎搜到你的網(wǎng)站的內(nèi)容。

使用 HTTP 協(xié)議進(jìn)行通訊是用的明文,容易被偷看和篡改,所以不安全,那么不使用明文不就解決問題了嗎?

根據(jù)前面提到的對稱加密,我們可以使用對稱加密對通訊內(nèi)容進(jìn)行加密,然后服務(wù)端用相同的密鑰進(jìn)行解密。這個方案的痛點(diǎn)就在于,在互聯(lián)網(wǎng)中,通訊雙方如何安全的傳遞公鑰呢?

可以先使用非對稱加密對公鑰進(jìn)行傳遞,然后后續(xù)雙方使用公鑰進(jìn)行通訊。這個思路很不錯,而且非常安全。我們模擬一下現(xiàn)在的通訊流程:

用戶 A 請求服務(wù) B,服務(wù)端 B 發(fā)送自己的公鑰 pub_key 給 A,A 生成密鑰 key 并使用 pub_key 進(jìn)行加密然后發(fā)送給服務(wù)端 B,服務(wù)端使用 private_key 進(jìn)行解密拿到密鑰 key,然后后續(xù)使用該密鑰進(jìn)行通訊。

這個流程也是有問題的,問題就在于,在服務(wù)端發(fā)送自己公鑰給 A 的時候,如果此時 C 進(jìn)行了攔截,并且將自己的公鑰給到了 A,而 A 以為這個就是 B 的公鑰,那么后續(xù)通訊過程實(shí)際上就是 A 與 C 進(jìn)行通訊,A 的隱私信息全部都暴露給了 C。

看一下上面被攔截的流程,關(guān)鍵點(diǎn)在于,A 收到 C 的公鑰之后誤以為是 B 的,才會發(fā)生后面泄露隱私的問題。所以,如果能夠讓 A 識別服務(wù)端的公鑰,那么這個問題就可以被解決。那么接下來,認(rèn)證中心就登場了。

認(rèn)證中心

在現(xiàn)實(shí)生活中,你去火車站買票,或者去銀行辦理一些業(yè)務(wù),經(jīng)常遇到一件事,那就是請出示身份證。誒,為什么非要身份證呢?因?yàn)樯矸葑C能證明你的身份。誒,既然身份證就能證明我的身份,那我自己寫一張假的身份證,那我不就換身份了么?那肯定不行,因?yàn)樯矸葑C是具有公信力權(quán)威機(jī)構(gòu)(比如說公安局)頒發(fā)的,是無法偽造(理想狀態(tài)下,即使偽造也會被識別,所以不要杠這個問題)的。

那么以上關(guān)鍵點(diǎn),具有公信力的權(quán)威機(jī)構(gòu),無法偽造。那么相同的道理,如果找個權(quán)威的機(jī)構(gòu),然后為這個公鑰頒發(fā)一個其他人無法偽造證書,上面就標(biāo)明了,這個公鑰確實(shí)隸屬于 xxx 服務(wù)端,那么當(dāng)客戶端拿到這個公鑰和證書的時候,不就可以確定這個公鑰確實(shí)屬于我要訪問的服務(wù)器了么,那么后續(xù)就可以安全又愉快的通訊了。

CA 是 Certificate Authority,即證書頒發(fā)機(jī)構(gòu),也稱為電子商務(wù)認(rèn)證中心、電子商務(wù)認(rèn)證授權(quán)機(jī)構(gòu),是負(fù)責(zé)發(fā)放和管理數(shù)組證書的權(quán)威機(jī)構(gòu),并作為電子商務(wù)交易中受信任的第三方,承擔(dān)公鑰體系中公鑰的合法性檢驗(yàn)的責(zé)任。

認(rèn)證中心比較好解決,具有公信力的權(quán)威機(jī)構(gòu)都可以,但是如何做到無法偽造呢?如果能夠輕易偽造,那么上訴仍然不成立。

回頭看一下,我們前面說非對稱加密作用時候的總結(jié):

使用私鑰加密只有公鑰才能解密,可以用來身份認(rèn)證。只要你能確定這個公鑰是我的公鑰,那么不管這個信息來自于哪里,只要能解密,就意味著是我發(fā)出的。

誒,非對稱加密可以用作身份認(rèn)證,那這里認(rèn)證中心(CA)需要的就是身份認(rèn)證,CA 需要告訴客戶端,這個證書就是他頒發(fā)的。

所以流程就是這樣,CA 使用私鑰對證書進(jìn)行加密,然后頒發(fā)給服務(wù)端,服務(wù)端在下次通訊的時候就會把自己的公鑰和證書一并下發(fā)給客戶端,誒,你看這個公鑰就是我的,證書在此,別人無法偽造,放心用吧。那么客戶端使用 CA 的公鑰對證書進(jìn)行解密,如果可以解密并且證書信息正確,那么就說明一切正常,然后客戶端繼續(xù)上面我們說的流程進(jìn)行通訊。perfect~~

這里可能有人又會提疑問了,誒,那客戶端怎么對證書進(jìn)行解密呢?那不得先知道 CA 的公鑰么?那我獲取 CA 的公鑰的時候怎么確定這個公鑰不是偽造的呢?這個其實(shí)不用擔(dān)心,因?yàn)樵诓僮飨到y(tǒng),甚至某些瀏覽器中就已經(jīng)保存了受信任的 CA 的信息。我們可以簡單理解為 CA 的公鑰,其實(shí)是有頂級認(rèn)證中心的,也就是認(rèn)證中心要去頂級認(rèn)證中心去進(jìn)行認(rèn)證,然后認(rèn)證中心也會有證書,這些證書預(yù)裝在操作系統(tǒng)里面,所以給自己電腦裝證書的時候務(wù)必謹(jǐn)慎,否則坑的是自己。

那么到這里,整個流程就都是安全的了。接下來,我們看一看如何為自己的網(wǎng)站申請證書。

證書的申請

目前 CA 有很多,但是大都收費(fèi),感興趣的自己百度就行。本文只提一種免費(fèi)的解決方案 Let's Encrypt,因?yàn)楦F。

Let's Encrypt 是一個于2015年三季度推出的數(shù)字證書認(rèn)證機(jī)構(gòu),旨在以自動化流程消除手動創(chuàng)建和安裝證書的復(fù)雜流程,并推廣使萬維網(wǎng)服務(wù)器的加密連接無所不在,為安全網(wǎng)站提供免費(fèi)的SSL/TLS證書。

這玩意最牛逼的地方在于,它不僅免費(fèi),還提供了超級簡單的自動化工具 Certbot,小白用戶不用這個簡直天理難容。Certbot 官網(wǎng)提供了教程教你一步一步怎么做,一般用 Nginx 或者 Apache 服務(wù)器的小伙伴直接對著教程就能輕松搞定,因?yàn)檫@個工具有一種模式叫做 “Standalone”,可以檢測到你的服務(wù)器,然后給你服務(wù)器進(jìn)行一些配置,全自動完成。或者你也可以選擇 “Webroot”模式,自己配置。

Let's Encrypt 現(xiàn)在的版本已經(jīng)支持通配符域名證書的發(fā)放,簡單來說就是你的所有二級域名都可以通過一張證書來完成認(rèn)證。不過筆者沒那個需求,所以本文只申請了單個域名的證書。

  • 最簡單的方式安裝(以 Nginx 為例)

    1. 安裝 Certbot 插件

      # 如果是 Ubuntu,換 apt-get 即可,root 用戶可以不加 sudo
      sudo yum update
      sudo yum install certbot python-certbot-nginx
      
    2. 安裝證書

      sudo certbot --nginx
      

      這個命令執(zhí)行之后,certbot 會自動檢測你的服務(wù)器配置文件,然后讓你選擇要開啟的站點(diǎn),選擇之后,certbot 會下載證書并且為你更新配置文件的配置。

    3. 重啟服務(wù)器

      nginx -s reload
      
  • Webroot 模式(官方稱為插件)的大致步驟

    1. 安裝 Certbot

      sudo yum update
      sudo yum install certbot python-certbot-nginx
      
    2. 修改配置文件,在 server 模塊增加以下內(nèi)容

      location ^~ /.well-known/acme-challenge/ {
         default_type "text/plain";
         root     /usr/share/nginx/html;
      }
      
      location = /.well-known/acme-challenge/ {
         return 404;
      }
      
    3. 重啟,然后安裝證書

      # 將第一個參數(shù) arg0 改為你的靜態(tài)資源目錄,第二個參數(shù) arg1 改為你的域名
      sudo certbot certonly --webroot -w [arg0] -d [arg1]
      
    4. 新增 443 端口的配置

      # 同上,注意修改參數(shù)。arg0 改為靜態(tài)資源目錄,arg1 改為域名
      server {
              listen 443 ssl http2;
              server_name [arg1];
      
              ssl_certificate /etc/letsencrypt/live/[arg1]/fullchain.pem;
              ssl_certificate_key /etc/letsencrypt/live/[arg1]/privkey.pem;
      
              location / {
                      root [arg0];
              }
              // 復(fù)制其他你自定義的配置
      }
      
    5. 設(shè)置定時任務(wù),定時更新證書(證書有效期 90 天)

      sudo crontab -e
      # 添加以下內(nèi)容,每周一 2:30 執(zhí)行一次更新,并且將日志存放在指定目錄
      30 2 * * 1 certbot renew  >> /var/log/le-renew.log
      
  • Docker

    這個算是比較折騰的玩兒法,可偏偏筆者就是愛折(zhuo)騰(si),我的 nginx 是 docker 部署的,為什么非要用 docker 呢?主要是我不想讓自己主機(jī)一大堆亂七八糟的東西,所有東西都放 docker 里面,不需要了,直接整個容器扔掉。

    這里其他配置不變,nginx 的配置文件仍然按照上面配置,靜態(tài)資源目錄就用你容器的靜態(tài)資源目錄映射宿主機(jī)的目錄就行,然后主要的就是再增加一個目錄映射,如下:

      -v /etc/letsencrypt:/etc/letsencrypt
    

    其他大同小異,根據(jù)自己主機(jī)情況進(jìn)行修改。如果不知道該怎么改,思考一下申請證書的原理應(yīng)該就清楚了。大致流程是 CA 會給你下發(fā)一些任務(wù),然后如果你能夠完成這些任務(wù),就代表著你是域名的擁有者,那么就可以頒發(fā)證書,詳見參考文章。

總結(jié)

文章寫到這里差不多也就結(jié)束了,這里進(jìn)行一個小小的總結(jié)。為了數(shù)據(jù)安全,所以我們需要進(jìn)行數(shù)據(jù)加密,然后分別提到了對稱加密非對稱加密,雖然非對稱加密安全性特別好,但是效率太低,不適合大量使用,所以使用非對稱加密來傳輸對稱加密所需的密鑰就成了更加合適的方案,而這么做還有一個問題就是公鑰的傳輸問題,從而引入了認(rèn)證中心來對公鑰進(jìn)行認(rèn)證,也就是說告訴客戶端,這個公鑰確實(shí)屬于某某域名,不是第三發(fā)偽裝的,到這里一切問題就解決了。

最最后,分享一個更香的。如果你的域名是從阿里云購買的,阿里云為每個域名提供 20 張免費(fèi)的證書,通過認(rèn)證之后可以下載下來,然后直接放到服務(wù)器就一切搞定了,教程在這里,官方提供了各種情況下的文檔,真的是太太太香了~~~

參考

Let’s Encrypt

Certbot

如何免費(fèi)的讓網(wǎng)站啟用HTTPS -- 酷 殼 – CoolShell

Let’s Encrypt是如何工作的

手把手教你在Nginx上使用CertBot

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容