1. HTTPS
1.1. 什麼是HTTPS
HTTPS(HypertextTransfer Protocol Secure)即安全的HTTP。HTTPS的安全基礎是安全套接層(Secure Sockets Layer,SSL)。HTTP工作在應用層(OSI模型的最高層),SSL協議工作在一個較低的子層,位於TCP/IP協議和HTTP協議之間。在HTTP報文傳輸前對其加密,並在到達時對其解密。嚴格地講,HTTPS並不是一個單獨的協議,而是工作在SSL協議上的HTTP協議。
TLS對SSL進行了擴充,是SSL的繼任者,但兩者區別不大,以下討論中不對TLS和SSL做嚴格區分。
HTTPS主要作用有兩種:(1)確認通訊雙方的身份,(2)建立安全通道,保證數據傳輸安全。1.2. HTTPS的主要作用
1.2.1. 確認通訊雙方的身份
HTTPS通訊中,通過簽名技術通訊雙方可以確認對方身份。身份認證分爲單向認證和雙向認證。單向認證中只有服務器端有證書,雙向認證中服務器和客戶端都有證書。一般的HTTPS站點只有服務器有證書,而客戶端無證書。
單向認證是雙向認證的簡化版,本文討論過程中如無特殊說明都認爲是雙向認證。
1.2.2. 建立安全通道,保證數據傳輸安全
基於SSL協議通訊雙方可以協商一個用於對稱加密的密鑰,該密鑰是一個難以破解的隨機數,而且依賴通訊雙方的證書、私鑰等來協商。密鑰協商好後,通訊雙方用該密鑰對數據進行加解密,從而保證數據安全。
1.3. HTTPS與HTTP協議的差異
(1). HTTP 的URL是以“http://”開始,HTTPS的URL是以“https://”開始;
(2). HTTP默認端口爲80,HTTPS的默認端口爲443;
(3). 採用HTTPS的Web Server需要到CA申請證書;
(4). HTTPS由HTTP+SSL來實現,可進行加密傳輸、身份認證等,要比HTTP安全
(5). HTTP的信息是明文傳輸,而HTTPS的信息是加密傳輸
2. 公開密鑰加密
2.1. 什麼是公開密鑰加密?
公開密鑰加密也稱非對稱密鑰加密,該加密算法使用兩個不同的密鑰:加密密鑰和解密密鑰。前者公開,又稱公開密鑰,簡稱公鑰;後者保密,又稱私有密鑰,簡稱私鑰。這兩個密鑰是數學相關的,用某用戶加密密鑰加密後所得的信息只能用該用戶的解密密鑰才能解密。RSA算法(由發明者Rivest,Shmir和Adleman姓氏首字母縮寫而來)是著名的公開密鑰加密算法。
公鑰加密的另一用途是身份驗證:用私鑰加密的信息,可以用公鑰對其解密,接收者由此可知這條信息確實來自於擁有私鑰的某人。私鑰加密的過程即數字簽名。
用公鑰加密的數據只有私鑰才能解密;相反的,用私鑰加密的數據只有公鑰才能解密,正是這種不對稱性才使得公用密鑰密碼系統被廣泛應用。
2.2. 優點
與對稱密鑰加密相比,優點在於無需共享的通用密鑰,解密的私鑰不發往任何用戶。即使公鑰在網上被截獲,如果沒有與其匹配的私鑰,也無法解密,所截獲的公鑰是沒有任何用處的。
2.3. 過程
假設兩個用戶A,B進行通信,公鑰爲c,私鑰爲d,明文爲x.
Step 1. A用公鑰對明文進行加密形成密文c(x),然後傳輸密文;
Step 2. B收到密文,用私鑰對密文進行解密d(c(x)),得到要通信的明文
2.4. 對稱密鑰加密
對稱密鑰加密又叫專用密鑰加密,即發送和接收數據的雙方必須使用相同的密鑰對明文進行加密和解密運算。
3. 數字證書和CA
3.1. 確認主機的真實性
採用https 的server(服務器)必須從CA (CertificateAuthority)申請一個用於證明服務器用途類型的數字證書(或者叫CA證書). 該證書只有用於對應的server 時,客戶端纔信任此主機.
CA(Certificate Authority)即"認證機構",是負責簽發證書、認證證書、管理已頒發證書的機構,是PKI(Public Key Infrastructure,公鑰基礎設施)的核心。它要制定政策和具體步驟來驗證、識別用戶身份,並對用戶證書進行簽名,以確保證書持有者的身份和公鑰的擁有權。
CA 也擁有一個證書(內含公鑰)和私鑰。網上的公衆用戶通過驗證 CA 的簽字從而信任CA ,任何人都可以得到 CA 的證書(含公鑰),用以驗證它所簽發的證書。
3.2. 什麼是數字證書
數字證書(CA證書是經過認證的數字證書)是一個用於互聯網通訊中認證身份的工具,由權威機構——CA機構(Certificate Authority)發行。其作用類似於司機的駕駛執照和公民身份證。CA作爲公正的第三方來確保證書的有效性[6]。全國存在多個CA機構(只要你有公信力你也可以成立一家CA機構)。
數字證書包含一個公鑰以及該密鑰所有者的信息。證書還標明有有效期,並通過另一密鑰(CA私鑰)進行簽名,該密鑰能保證這些屬性的真實性,最重要的是,保證公鑰本身的真實性[14]。最簡單的證書包含一個公鑰、名稱以及證書授權中心的數字簽名(公開密鑰只是證書的一部分內容)。目前,證書的格式和驗證方法普遍遵循X.509 國際標準。
CA機構自身也擁有一個證書(內含公鑰)和一個私鑰。
用戶如果想得到一個數字證書,他應先向 CA申請,CA審查申請者的身份後,給他分配一個公鑰,並將公鑰與申請者的身份信息綁在一起,同時用自己的私鑰簽字,最終生成一個證書,發給申請者;同時還將一個與公鑰關聯的私鑰也發給申請者。證書的內容主要有:CA信息、CA簽字、證書擁有者信息、證書公鑰和證書有效期等。
某人需要驗證一個證書時,用簽發該證書的CA的公鑰來解密其簽名信息,以驗證證書是否可信。CA證書也需要驗證,驗證CA證書是一個遞歸上溯的過程,驗證過程終止於根證書。根證書是一份特殊的證書,它的簽發者是它本身,下載根證書就表明用戶對該根證書,以及其所簽發的證書都信任。
3.3. 數字證書基本原理
數字證書採用公開密鑰加密體制,利用一個強關聯的密鑰對進行加、解密。證書擁有者保存好自己的私鑰,用它進行解密和簽名;並把公鑰公開,供一組用戶所共享,用於加密和驗證簽名。
1、加密:發送數據時,發送方使用接收方的公鑰對數據加密,接收方用私鑰解密,還原消息。算法保證公鑰加密的數據只有對應的私鑰才能解密。
2、數字簽名:證書擁有者用私鑰對信息進行加密,由於私鑰僅爲本人所有,這樣就生成了別人無法僞造的數據,該數據即數字簽名。採用數字簽名,能夠確認以下兩點:
(1)保證信息是由簽名者所發送,簽名者不能否認或者難以否認;
(2)保證信息自簽發後到收到爲止,未曾做過任何修改,簽發的文件是真實的文件。
算法保證只有公鑰才能解開私鑰加密的信息。
3.4. 如何生成數字證書
略
4. SSL
4.1. 什麼是SSL
SSL 是一個安全協議,它提供使用TCP/IP 的通信應用程序間的隱私與完整性。傳輸層安全(Transport Layer Security,TLS)對SSL進行了升級改造,將成爲SSL的繼任者。
4.2. 加密過程
SSL 協議既用到了公鑰加密技術(非對稱加密),又用到了對稱加密技術。
Step 1:用公開密鑰加密技術(通常爲RSA)驗證彼此身份(有時服務器不需要驗證客戶端身份),並協商Step2中通訊時所用的對稱加密密鑰;
Step 2:用對稱密鑰加密技術(如DES,或者RC4)加密服務器端和客戶端通訊時的數據。
這樣做的好處是:公開密鑰加密相對複雜,速度慢,可用來完成安全性要求較高的身份認證、密鑰協商等事務;對稱密鑰加密技術相對簡單,速度快,可用來加密數據量大的傳輸內容。
4.3. 構成
SSL協議的優勢在於它與應用層協議是獨立無關的。高層的應用層協議 (例如:Http、FTP、Telnet等等 ) 能透明的建立於SSL協議之上。SSL協議在應用層協議通信之前就已完成數據加密、通信密鑰的協商和服務器的認證等工作。在此之後應用層協議所傳送的數據都會被加密,從而保證通信的私密性。
SSL協議位於TCP/IP協議與各種應用層協議之間,爲數據通訊提供安全支持。SSL協議可分爲兩層:記錄協議(SSL Record Protocol)和握手協議(SSL Handshake Protocol)。記錄協議建立在可靠的傳輸協議(如TCP)之上,爲高層協議,如握手協議,提供數據封裝、壓縮、加解密等支持。握手協議建立在SSL記錄協議之上,用於在實際的數據傳輸開始前,通訊雙方進行身份認證、協商加密算法、交換加密密鑰等。握手協議協商好加密算法、壓縮算法和對稱加密密鑰等後,開始應用層數據傳輸(如HTTP協議的數據傳輸)。應用層的數據傳輸也是工作在記錄協議之上,由記錄層用協商好的密鑰對其數據進行加解密,確保數據安全。
4.4. RSA算法
1977年美國麻省理工學院的Ron Rivest、Adi Shamirh和LenAdleman共同發明了RSA加密算法。。該算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但要對其乘積進行因式分解卻極其困難。
4.5. SSL協議的身份認證和對稱加密密鑰的協商
4.5.1. TSL協議交互過程
TSL的身份認證和密鑰協商大致過程如下(下面只考慮新建會話的情況,而不考慮重啓存在會話的情況):
Step1:客戶端往服務器端發ClientHello消息
消息特點:該消息是客戶端連接服務器端時發送的第一個消息。
消息構成:
(1). 使用的TLS協議版本。
(2). 隨機數;用於計算對稱加密時的“主密碼”。
(3). 會話ID;重連時有用,可爲空。
(4). 加密算法列表;客戶端支持的加密算法列表,並按照客戶端的偏好從前往後排。
(5). 壓縮算法列表;客戶端支持的壓縮算法列表,並按照客戶端的偏好從前往後排。
(6). 擴展信息。
消息作用:用於發起會話、交換隨機數、協商加密算法、壓縮算法等。
Step2:服務器端驗證ClientHello消息,主要驗證:
(1) 消息格式是否合法;
(2) 能否至少支持客戶端所列舉的一個加密算法和一個壓縮算法等。
驗證不通過則發送消息斷開會話,驗證通過則執行下一步。
Step3:服務器往客戶端發送ServerHello消息。
消息特點:該消息是服務器收到ClientHello後返回給客戶端的第一個消息。
消息構成:
(1). 使用的TLS協議版本。
(2). 隨機數;用於計算對稱加密時的“主密碼”(這個隨機數是服務器發送給客戶端的,跟第一步驟的隨機數不同,第一個是客戶端發送給服務的)
(3). 一個加密算法;服務器從客戶端的加密算法列表中選中的一個加密算法。
(4). 一個壓縮算法;服務器從客戶端的壓縮算法列表中選中的一個壓縮算法。
(5). 會話ID;新建的唯一的會話ID。
(6). 擴展信息。
消息作用:用於交換隨機數、確定加密算法、壓縮算法等。
Step4:服務器往客戶端發送Certificate消息。
消息特點:該消息必須在ServerHello發送完後立即發送。如果是匿名協商,則無須發該消息。
消息構成:
(1). 證書列表;服務器的證書必須爲證書列表的第一個,其後爲簽發服務器證書的證書,依次類推,最後一個證書爲根證書籤署的證書。根證書不在證書列表中,它是通過其他途徑給到客戶端的。(好多時候是瀏覽器預裝好的)
消息作用:發送服務器證書,或者證書鏈。
Step5:服務器往客戶端發送ServerKeyExchange消息。
消息特點:
(1). 該消息必須在Certificate發送完後立即發送(如果是匿名協商,則該消息緊跟在ServerHello後)。
(2). 該消息只有當Certificate消息無法提供足夠信息讓客戶端完成“預主密碼”交換時才需要。
消息構成:
(1). 密鑰交換算法
消息作用:該消息用於發送密鑰交換算法給客戶端。客戶端可利用這些算法和服務器端完成“預主密碼”的交換。
Step6:服務器往客戶端發送CertificateRequest消息。
消息特點:
(1). 非匿名的服務器可通過該消息來要求客戶端發送證書驗證其身份。
(2). 如果發送該消息則該消息在ServerKeyExchange發送完後立即發送(如果該次交互不發送ServerKeyExchange,則該消息緊跟Certificate消息)
消息構成:
(1). 證書類型列表;客戶端的證書類型必須是證書類型列表中一種。
(2). 簽名和哈希算法列表;列舉服務器所支持的簽名算法和哈希算法。
(3). CA名字列表;服務器只接受的列表中所列出的CA所發行的證書,其他證書無法驗證。
消息作用:請求客戶端發送證書驗證其身份。(只有雙向認證才需要,即服務器也需要認證客戶端)
Step7:服務器往客戶端發送ServerHelloDone消息。
消息特點:
消息構成:
(1). 無消息內容。
消息作用:該消息用來告訴客戶端ServerHello以及附屬消息都已發送完畢。發完該消息後服務器等待客戶端消息。
Step8:客戶端往服務器端發送ClientCertificate消息。
消息特點:
(1). 該消息僅當收到服務器CertificateRequest時才發送,即服務器要求驗證客戶端。
(2). 如果發送該消息,則該消息必須是客戶端收到ServerHelloDone消息後發往服務器的第一個消息。
消息構成:
(1). 證書列表。
消息作用:發送客戶端證書讓服務器認證。(只有雙向認證才需要,即服務器也需要認證客戶端)
Step9:客戶端往服務器端發送ClientKeyExchange消息。
消息特點:
(1). 如果有ClientCertificate消息,則該消息必須緊跟其後發送;如果無ClientCertificate消息,則該消息是收到ServerHelloDone消息後發往服務器的第一個消息。
(2). 消息用RSA算法或者 Diffie-Hellman參數來協商預主密碼。
(3). 採用RAS加密的協商預主密碼時,先生成一個長的隨機數,由該隨機數和客戶端的TSL版本號構成一個結構體,用服務器證書的公鑰(從服務器證書獲得)對結構體進行加密,並把加密後的數據發給服務器。
(4). Diffie-Hellman參數協商比較複雜,暫不討論。
消息構成:因加密算法而異。
消息作用:協商預主密碼
Step10:客戶端往服務器端發送CertificateVerify消息。
消息特點:
(1). 該消息只有當客戶端證書有簽名能力時(Tenfy:即有客戶端證書,且證書是公鑰和私鑰都有的)發送,其它情況不發送(不含固定Diffie-Hellman參數的證書都有簽名能力)。
(2). 該消息必須在ClientKeyExchange發送完後立即發送。
(3). 該消息採用客戶端證書中的私鑰信息進行加密。
消息構成:
(1). 把該消息之前的所有消息作爲參數,用私鑰對其進行簽名得出一份數據,該數據即爲消息體。
消息作用:通過簽名方式,驗證客戶端身份。
Step 11:服務器用服務器私鑰解密ClientKeyExchange消息得 “預主密碼”。服務器和客戶端用相同的算法計算“主密碼”。主密碼計算是根據預主密碼、ClientHello中的隨機數、ServerHello中的隨機數得到的。計算好主密碼後雙方各向對方發送一個ChangeCipherSpec消息:
消息特點:
(1). 該消息必須在所有握手消息發送完之後,在Finished消息發送之前發送。
(2). 該消息必須在接收完所有握手消息之後,在接收Finished消息之前收到。
消息構成:
(1). 確認消息。
消息作用:確認採用剛纔協商好的壓縮算法、加密算法、主密碼等來傳輸後繼數據。
Step12:任意一方收到ChangeCipherSpec消息後告訴自己的Record Layer由讀等待狀態轉爲讀狀態,並採用新方式來傳遞數據。並往另外一端往發送Finished消息。
消息特點:
(1). 該消息是收到ChangeCipherSpec後立即發送的。
(2). 該消息是首次採用剛纔協商好的壓縮算法、加密算法、主密碼等來傳輸的數據。
消息構成:
(1). 把前面大部分的握手消息作爲參數,用相同的算法計算得到的一個值。
消息作用:完成壓縮算法、加密算法等的協商,開始轉入應用層數據傳輸。
Step13:雙方驗證收到的消息,驗證通過則開始應用層數據傳輸,否則斷開。
TSL通訊時分爲單向認證和雙向認證。單向認證時只需要服務器端擁有證書(公鑰是證書的一部分)和私鑰,其中證書公開,私鑰自己保管;雙向加密時需要服務器和客戶端都提供證書和私鑰,證書都公開,私鑰都自己保管。這兩個對證書、私鑰對無必然聯繫,實際編程時把它們作爲兩對獨立的證書、私鑰對來處理。
單向認證時,服務器端不會驗證客戶證書。故服務器無須發送CertificateRequest消息請求客戶端證書,客戶端無須發與證書相關的ClientCertificate和CertificateVerify消息。
4.5.2. TSL協議中的消息驗證
通訊過程中必須嚴格按上述說明來發送和接收消息。接收方接收消息後一旦發現:(1)消息遺漏,(2) 消息次序不對,(3) 消息格式(如加密格式)有誤,(4) 消息內容有誤,(5) 自身致命錯誤等,接收方立即通過Alert Protocol往發送方發送ErrorAlert消息,告訴對方終止此次會話。如果是能容忍的錯誤,則不發任何消息,以免對方主動斷開會話。
若干重要驗證說明:
1. 客戶端驗證服務器的Certificate消息。主要驗證內容爲:
(1). 服務器證書使用日期是否有效。
(2). 發行服務器證書的CA是否可靠。
(3). 發行者的公鑰能否解開服務器證書上的“發行者數字簽名”。
(4). 服務器證書上的名稱(如域名)是否和服務器實際名稱匹配等(PHP中可以選擇是否驗證該選項)。
(Tenfy: 這裏可以看出,客戶端驗證服務的時候,只需要驗證對應服務器證書的有效性即可,無需驗證對應服務器是否擁有跟該證書一致的私鑰)
2. 服務器驗證客戶端的CertificateVerify消息。主要驗證內容爲:
(1). 用客戶端公鑰能否解開客戶端私鑰加密的消息。
(Tenfy:服務器驗證客戶端時候,還需要驗證是否擁有跟證書對應的私鑰)
3. 服務器驗證客戶端的ClientCertificate消息。主要驗證內容爲:
(1). 客戶的證書使用日期是否有效。
(2). 爲客戶提供證書的CA 是否可靠。
(3). 發行CA 的公鑰能否正確解開客戶證書的發行CA的數字簽名。
(4). 檢查客戶的證書是否在證書廢止列表(CRL)中。
附:常見的證書格式
1.1. PEM
Openssl使用PEM(RFC 1421-1424)文檔格式。PEM全稱是PrivacyEnhanced Mail,該標準定義了加密一個準備要發送郵件的標準。它的基本流程是這樣的:
1、信息轉換爲ASCII碼或其它編碼方式;
2、使用對稱算法加密轉換了的郵件信息;
3、使用BASE64對加密後的郵件信息進行編碼;
4、使用一些頭定義對信息進行封裝,這些頭信息格式如下(不一定都需要,可選的):
Proc-Type,4:ENCRYPTED
DEK-Info:cipher-name, ivec
其中,第一個頭信息標註了該文件是否進行了加密,該頭信息可能的值包括ENCRYPTED(信息已經加密和簽名)、MIC-ONLY(信息經過數字簽名但沒有加密)、MIC-CLEAR(信息經過數字簽名但是沒有加密、也沒有進行編碼,可使用非PEM格式閱讀)以及CLEAR(信息沒有簽名和加密並且沒有進行編碼,該項好象是openssl自身的擴展,但是並沒有真正實現);;第二個頭信息標註了加密的算法以及使用的ivec參量,ivec其實在這兒提供的應該是一個隨機產生的數據序列,與塊加密算法中要使用到的初始化變量(IV)不一樣。
5、在這些信息的前面加上如下形式頭標註信息:
-----BEGINPRIVACY-ENHANCED MESSAGE-----
在這些信息的後面加上如下形式尾標註信息:
-----ENDPRIVACY-ENHANCED MESSAGE-----
上面是openssl的PEM文件的基本結構,需要注意的是,Openssl並沒有實現PEM的全部標準,它只是對openssl中需要使用的一些選項做了實現,詳細的PEM格式,請參考RFC1421-1424。
The Public-KeyCryptography Standards (PKCS)是由美國RSA數據安全公司及其合作伙伴制定的一組公鑰密碼學標準,其中包括證書申請、證書更新、證書作廢表發佈、擴展證書內容以及數字簽名、數字信封的格式等方面的一系列相關協議。
1.2. PFX
PFX(Personal Information Exchange)證書文件是採用PKCS(The Public-KeyCryptography Standards)標準生成的證書。PKCS是由美國RSA數據安全公司及其合作伙伴制定的一組公鑰密碼學標準,其中包括證書申請、證書更新、證書作廢表發佈、擴展證書內容以及數字簽名、數字信封的格式等方面的一系列相關協議。
PFX文件通常包含一個證書和與之對應的私鑰,現階段證書採用PKCS #12 標準[14]。這類文件是高度敏感的,在導出密鑰對時,Windows 提供用密碼加密 .pfx 文件;而在導入密鑰對時,您必須再次提供此密碼方可導入。
1.3. CER
擴展名爲 .cer 的文件採用 X.509v3 格式ASN.1 ,並由CA簽名。這些文件中包含着一個公鑰和額外的信息。這些文件一般用來提供給業務合作伙伴,以便他們能夠使用公鑰加密數據。
1.4. Java Key Store
Java Key Store(JKS)是Java語言中給出的一種密碼保護的文件,可存儲密鑰和證書。JKS文件好比一個倉庫,爲防範別人隨便亂拿,倉庫可以設置一把鎖,即JKS文件的密碼(storepass)。倉庫裏可存放多種密鑰,如公鑰、私鑰和密鑰對(由配對公鑰和私鑰組成)。每個密鑰都有一個名字,稱爲別名(alias)。倉庫裏的公鑰只要你能進入倉庫你就可以隨便查看拿走,私鑰則是有密碼的(keypass),只允許有權限的人查看拿走。所以從JKS文件中讀取公鑰只需要知道JKS文件(倉庫)的密碼即可,但讀取私鑰時則還必須有私鑰的密碼[1]。