應用層協議大多數本身都沒有實現加解密功能,好比http等。http就是直接把數據加載進來而後作簡單編碼(也就是流式化)而後響應客戶端,而後數據在瀏覽器展現,這個數據在傳輸過程是明文的,你截獲就能夠直接查看。這顯然不安全,要想作到安全那麼就只能在發送端加密而後接收端還能把信息還原成原來的內容,這就是加密解密。其實這個事情很好理解,加密解密在古代就有也不是現代的概念。在安全通訊裏面我常常聽到的2個東西就是SSL和TLS,這2個有什麼區別呢?以及HTTPS是怎麼通訊的?算法
SSL是網景公司研發的一種功能模塊這種模塊或者叫庫就在應用層和傳輸層之間又加了一層,並且不是一整層只是半層,這要作的好處是你調用這個庫就可使用這個功能若是不調用則仍是按照以前的方式來使用,這個半層的庫就是SSL,叫作安全套接字層。不過SSL只是一種規範和協議並非具體實現。OpenSSL則是對SSL的實現並且衆多實現中的一種。什麼叫作一種實現呢?好比httpd和Nginx這兩個應用都是http協議的實現或者說x86是一種標準那麼DELL和HP均可以基於這種標準來設計本身的電腦。瀏覽器
若是你本身自己不具有開發這種加密解密的功能,那麼你就可使用SSL完成這個工做,不過不管你本身開發仍是使用SSL,這些加密解密協議都須要具有2個基本功能:安全
加密和解密服務器
祕鑰分發併發
在Web應用方面,http調用了ssl就變成了https,雖然就是調用了ssl,可是http和https這兩個在機制上有巨大的區別。工具
叫作傳輸層安全,爲何有了SSL還會有一個和SSL相似的TLS呢?由於SSL協議是發明者是網景公司,它擁有版權,並且互聯網公司不少都須要使用安全通訊,因此國際標準化機構就參照SSL弄了一個TLS協議。二者兼容。TLS由IETF在1999年發佈。那麼因爲SSL的3個版本有漏洞全部不少不用了。如今主流都使用TLS。總之你能夠把TLS當作SSL使用其原理都是同樣的。性能
早期使用SSL較多後來大部分使用TLS,雖然咱們平時會說ssl它可能指的是SSL也能夠是TLS,因此你不用糾結它指的是什麼你只要理解爲一種安全通訊機制就能夠。因此咱們後面會不加區分的統稱SSL。網站
以前不少網站都不是https,也只有某些特殊階段才使用,好比支付階段、登陸驗證階段。那麼後來爲何你們包括百度搜索首頁這種都變成https了呢?ui
若是使用SSL加密那麼服務端就須要解密,加解密其實很是消耗CPU資源,早期處於性能考慮不會大面積使用SSL,好比只是普通的瀏覽網頁不必進行安全通訊。可是後來服務器性能愈來愈強並且大規模使用x86服務器以及有些網卡也支持SSL卸載,因此全站使用SSL也成爲可能。編碼
不過因爲http是明文傳輸的,用戶訪問什麼網頁其實能夠經過流量攔截,數據能夠被修改,有些不法行爲就能夠利用這一點來實現廣告投放,可是使用https通訊則不會出現這種狀況。
安全通訊到底怎麼安全呢?
爲了解決安全問題實現安全目標好比保密性、完整性、可用性等其解決方案有兩類,就是技術和服務,技術指的是加密和解密;服務指的是認證機制和訪問控制機制。
針對加密和解密以及實現服務功能的所用到的加密算法和協議就有以下幾種:對稱加密、非對稱加密、單向加密和認證協議。
在Linux上實現上述算法和協議的工具備OpenSSL(ssl協議的實現)和GPG(pgp協議的實現)。
先說一下算法,雖然加密用祕鑰可是如何用這個祕鑰來對數據加密或者解密這個是算法來決定的,可是一般算法是公開的好比RSA(個別安全公司有本身的獨有的算法除外)因此是否安全不取決於算法而是祕鑰。
什麼叫密碼,什麼叫祕鑰?我上面那段話確定會有人迷糊,密碼是編碼和解碼的規則你能夠理解爲加密和解密規則而祕鑰則是改變密碼行爲的外在參數,也就是說相同的規則當你使用不一樣的祕鑰加密相同內容時加密後的結果也是不一樣的。好比字母移位這就是密碼,而移動N位的這個N則是祕鑰。假設移動3位,那麼ABC則變成DEF。因此這就是爲何上面那段話的結論是不取決於算法(密碼)而是祕鑰。
對稱祕鑰加密:對稱加密算法有不少,可是不管什麼算法加密解密都使用相同的祕鑰,好處是簡單計算量小也就是不會對CPU產生太大壓力,缺點以及密碼過多(你要和不少人通訊就須要不少人的密碼)、密碼分發困難。由於你要讓對方能夠解密你就須要把密碼先給對方,這個給密碼的過程要不要加密呢?這就變成了先有雞仍是先有蛋的事情永遠扯不清。經常使用算法DES(目前已經棄用)、AES等。
非對稱祕鑰加密:有公鑰和私鑰,使用公鑰加密私鑰解密。若是A和B通訊每一個人都有一對兒公鑰和私鑰,彼此還都有對方的公鑰。A發信息給B則使用B的公鑰加密,而後B收到後使用本身的私鑰解密,而後B回覆信息給A則使用A的公鑰加密,A收到後使用本身的私鑰解密。這個過程看似完美,但是因爲公鑰你們都能獲取,B怎麼知道信息是來自A而不是來自其餘冒名A的人呢?這就是數字簽名,這個後面再說。非對稱加密主要用於數字簽名和祕鑰交換。加密數據雖然它也能作可是一般不這麼用,你看後面的HTTPS通訊過程就知道了。非對稱加密主要用來作對稱祕鑰的交換,完成交換後你們其實就是使用對稱密碼來作數據加密和解密。經常使用算法RSA(加解密和簽名)、DSA(僅能簽名)等。
單向加密**:不可逆的,只能加密不能解密,好比MD五、SHA1等。其實主要用來提取數據摘要或者說指紋,因此並不能算做咱們常規意義上的加密。它的特色是數據微小變化都會致使指紋的不一樣,因此主要用來作數據完整性驗證。
特別注意:並非說只能用公鑰加密私鑰解密,非對稱加密方式的目的就是使用一種祕鑰加密的數據必須能使用另一種祕鑰解密,因此不管是公鑰仍是私鑰均可以加密,咱們之因此說用公鑰加密用私鑰解密是首先是由於公鑰是從私鑰中提取出來的,其次公鑰是公開的若是你用私鑰加密那麼任何擁有該私鑰對應公鑰的人均可以解密 。因此纔有公鑰發給其餘人私鑰本身留存且用公鑰加密私鑰解密,由於只有這樣才能發揮這種非對稱加密或者說公鑰加密的主要做用也就是密碼交換和數字簽名。不過使用私鑰加密數據能夠證實一件事情就是若是用該私鑰的公鑰能夠解密那就證實這個數據必定是私鑰持有人發來的。
祕鑰交換(IKE,互聯網祕鑰交換):IKE實現的方式有公鑰加密和DH算法。這種標準主要用來作祕鑰交換。不過對於祕鑰交換來講更加安全的實際上是DH算法,雖然經常使用的是公鑰加密方式。
公鑰加密最大的問題是密碼是要從一方傳送到一方,雖然使用對方的公鑰加密了。可是DH的好處是雙方不用發密碼並且雙方還能夠獲得密碼。
數字簽名的主要做用是爲了檢查數據是否被篡改以及數據是誰發的(就是向對方證實此時他收到的消息是來自消息宣稱的人本人而不是冒名頂替的第三人,固然真正驗證對方身份的還不能僅僅靠數字簽名這個後面再說)。
按照上面的例子A發消息給B,A使用B的公鑰加密,B經過本身的私鑰解密,但是公鑰你們均可以得到那麼B怎麼知道這個消息是來自A呢?難道僅僅憑藉消息內容說我是A就判定消息來自A麼?另外B怎麼肯定信息在傳遞過程當中沒有被篡改呢?
爲了解決這個問題A對消息作哈希摘要(MD5算法或者SHA1算法等)而後用A本身的私鑰對摘要進行加密(數字簽名),而後把加密後的摘要和消息自己一塊兒使用B的公鑰加密發送給B,這樣B收到消息後用本身的私鑰能夠解密,而後用A的公鑰能夠解密簽名(上面提到的摘要)若是成功就說明消息來自A。這就是簽名和驗證簽名過程。消息來源確認了,此時就會擔憂消息傳遞過程當中若是被篡改怎麼辦?這就是那段被加密的摘要的做用,若是B使用相同的算法來計算信息的摘要,若是B計算獲得的值和解密簽名後的獲得的值一致說明信息沒有被篡改。
上面的過程的確看起來很好可是有一個漏洞就是全部的公鑰都要本身保存和管理萬一被別人替換了呢,或者說A和B從未通訊過如今要作第一次通訊如何把公鑰給對方呢?難道就不怕有人冒充A把本身的公鑰給了B那麼反過來也是同樣,另外A對信息作哈希摘要的時候用的什麼算法,萬一B沒有這個算法怎麼辦呢,因此這就引出了CA和證書的概念。
公鑰加密私鑰解密,私鑰確定是本身保存其實也就保存一份,若是我須要給不少人通訊難道我要保存不少人的公鑰麼?若是這個數量達到一個量級在管理上也很困難另外就是如何防止公鑰被篡改呢也就是如何驗證這個公鑰是否是我要通訊的那我的的公鑰而不是別人發來冒充他的。若是要是有一個第三方機構來統一管理就行了,這就是CA證書管理機構。CA的做用就是對申請人的公鑰進行認證和加密,加密後的公鑰就是數字證書,又稱CA證書,證書中包含了不少重要信息好比申請人、用途、申請人支持的加密算法、申請人使用hash算法,證書有效期等其中最重要的就是證書申請人的公鑰。固然前提是通訊雙方都要信任同一個CA機構。
那有了CA以後該怎麼作呢?申請者須要本身生成本身的公鑰和私鑰,而後把公鑰和其餘申請信息發給證書頒發機構,證書頒發機構本身也有公鑰和私鑰,而後證書頒發機構提取申請者的公鑰和其餘信息的特徵碼,而後CA使用本身的私鑰加密這個特徵碼也就是簽名, 這樣造成一個由CA簽名的證書而後發送給申請者 。此時仍是A和B通訊且爲第一次通訊而且雙方都信任同一CA頒發機構 。
上述這個過程就是你們經過CA來間接獲取通訊雙方公鑰的過程。若是B使用CA的根證書沒法解密A發來的證書說明就說明A的證書不是該CA簽發的,因爲世界上公認的CA也就那麼幾個因此若是B用這些CA的根證書都解密不了A的證書,那麼就會提示風險,頗有可能A這個證書就是一個自簽名的證書。
這裏咱們只是闡明概念,在實際應用中上述過程還有些不一樣,好比上面A發給B的包括簽名和證書以及信息,難道信息不加密麼?若是加密用什麼加密等。這些東西都會在具體應用場景中再說明。
既然明白了CA那麼咱們就說一下PKI。
公鑰基礎設施,以CA爲中心所生成的一套體系就是PKI。它有四個重要組件:
簽證機構,就是CA,這個是負責生成證書的
註冊機構,就是RA,這個是負責接收證書申請的
證書吊銷列表,就是CRL,這個是標記哪些證書已經不可用或者不可信了,至關於證書黑名單,這裏的證書都不能被信任了。
證書存取庫,就是CB,這裏存放的是CA發的證書能夠供其餘人下載和使用
首先要說一下X.509,它就是證書標準,也叫作證書格式。全部證書都要符合這個標準,它定義了證書中包含那些內容。好比版本號、序列號(CA發的第幾個證書)、簽名算法ID(這個證書用什麼算法作的簽名)、CA頒發機構名稱、證書有效期、申請者名稱、申請者公鑰、CA頒發機構的惟一標識、申請者的惟一標識、CA對該證書的簽名(用CA本身的私鑰對全部信息的摘要作簽名)等擴展信息。下面就看看證書中常見的字段:
字段 | 含義 |
---|---|
Common Name | 簡稱CN,對於SSL證書來講通常爲網站域名;而對於代碼簽名證書則爲申請單位名稱;而對於客戶端證書來講則是申請者名稱也能夠當作用戶帳號名稱 |
Organization Name | 簡稱O,對於SSL證書來講通常爲網站域名;而對於代碼簽名證書則爲申請單位名稱;而對於客戶端證書來講則是申請者名稱也可當作用戶帳號所屬的組 |
Locality | 簡稱L,表示城市 |
State/Provice | 簡稱ST,表示省份 |
Country | 簡稱C,表示國家,好比中國爲CN,美國爲US |
瀏覽器使用HTTPS訪問時它是怎麼檢查證書和地址欄中的名稱呢?有下面三種方式
咱們知道了X.509是證書格式,但是不少時候看到的.pem、.key都什麼呢?,這裏就要作一些區分,證書編碼格式和證書擴展名。
全部的證書都是經過X.509標準生成的證書,可是有2中編碼格式:
PEM(Privacy Enhanced Mail),它是基於X.509標準生成的,文件可讀能夠直接打開查看,它是以"-----BEGIN CERTIFICATE-----" 和 "-----END CERTIFICATE-----"開頭和結尾且用Base64編碼的證書,這種編碼格式的證書一般是.pem擴展名。
使用命令 openssl x509 -in XXX.pem -text -noout
來查看證書內容。
DER(Distinguished Encoding Rules),二進制格式的,沒法直接讀取。
使用命令 openssl x509 -in XXX.der -inform der -noout 來查看證書內容。
雖然證書編碼格式有2種,可是擴展名有不少:
擴展名 | 說明 |
---|---|
.der | 用於DER編碼的證書 |
.pem | 它是基於X.509標準生成的,它是以"-----BEGIN CERTIFICATE-----" 和 "-----END CERTIFICATE-----"開頭和結尾且用Base64編碼的證書 |
.crt | 這種擴展名的證書能夠是DER編碼也能夠是PEM編碼,在Unix系統中常見。 |
.cer | 微軟系統常見,在微軟系統中能夠將.crt轉換爲.cer。一樣能夠是DER編碼也能夠是PEM編碼。 |
.key | 用於存儲公鑰和私鑰,一樣可使用DER或者PEM編碼。 |
.csr | 這個不是證書文件,而是證書籤名請求文件,向CA申請得到簽名證書時須要提供的申請文件。 |
上圖爲SSL的雙向驗證過程
HTTPS訪問一般使用單向認證,好比你訪問百度、淘寶、京東等雖然是https通訊可是它們不會去驗證客戶端證書,客戶端只會去驗證服務端證書。爲何呢?由於證書花錢啊,哪一個網站要是須要作客戶端證書認證那麼估計就沒有人去訪問了,再有對於服務端來講它不在意你是誰來的人越多越好。固然也有通訊雙方要求作雙向認證的好比登陸網銀的U盾就是客戶端證書。
驗證證書的合法性和有效性(使用客戶端保存的CA根證書的公鑰解密服務端發來的證書的簽名,解密成功說明服務端證書能夠信任,而後使用HASH算法計算證書摘要而後對比解密簽名後獲得的摘要,若是一致則說明內容沒有篡改,而後 檢查證書中的其餘信息,能夠檢查證書中的域名和我訪問的域名是否一致 (這裏防止釣魚網站)、檢查是否過時、檢查是否被吊銷等,若是檢查都經過則證書受信任,則瀏覽器欄裏面會顯示一個小鎖頭,不然會給出證書不受信的提示。
若是證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串隨機數,而後把隨機數、編碼變動通知(表示隨後的通訊都使用雙方商定的協議版本以及加密算法)和客戶端握手結束通知發送給服務器
這時候服務端會有3個隨機數,2個是客戶端發來的,一個是服務端本身產生的,用着三個隨機數並結合對稱加密算法生成「會話密碼」
生成編碼變動通知、服務端握手結束通知
使用商定好的HASH算法對會話密碼、編碼變動通知、握手結束通知計算摘要,而後使用本身的私鑰進行對摘要進行簽名,最後使用客戶端公鑰加密信息併發送給客戶端
這裏爲何在認證經過後的數據傳輸使用認證過程產生的隨機密碼呢?這是由於使用對稱加密解密性能要比非對稱的高,尤爲是對服務端的CPU壓力比較小,可是若是使用一個長期固定的對稱密碼就很不安全而隨機生成的就會有一個如何告訴通訊雙方且傳遞過程當中不被竊取的問題因此就使用非對稱加密方式這樣不但保證了隨機密碼的安全同時也能夠驗證服務端身份的真實性。
爲何會產生這麼多隨機數呢?爲了不計算機上產生的隨機數不是真的隨機數,因此雙方都產生隨機數而後使用你們的隨機數來生成密碼。