1. 程式人生 > >SSL和TLS-TLS 1.2

SSL和TLS-TLS 1.2

SSL和TLS-TLS 1.2

2008年,TLS 1.2(版本號是3.3)釋出(RFC 5246)。
TLS 1.2最大的改變是它的擴充套件機制,允許不改變底層協議的情況下,增加附加功能。

TLS Extensions

客戶端和伺服器的hello訊息裡,可以增加一些擴充套件。這些擴充套件是向後相容的。客戶端可以呼叫一個TLS擴充套件,來擴充套件它的ClientHello訊息,一個擴充套件了的ClientHello訊息就是一個帶附加的資料塊(擴充套件列表)的普通的ClientHello訊息。記住,這些附加的資訊只能擴充套件ClientHello訊息。這樣的一個擴充套件了的ClientHello訊息符合規範,不會破壞一個存在的TLS伺服器。TLS伺服器能接受這樣的訊息,即使它不理解這些擴充套件。如果伺服器理解這些擴充套件,它就返回一個擴充套件了的ServerHello訊息。
擴充套件了的ServerHello訊息只能用來響應擴充套件了的ClientHello訊息。
擴充套件列表的長度沒有上限。
每個擴充套件的結構都相同,有兩個屬性,兩個位元組的type和變長的data(可以為空)。比如,一個客戶端想初始化安全重新協商擴充套件,就在ClientHello訊息後面附加五個位元組(0xFF, 0x01, 0x00, 0x01和0x00)。前兩個位元組0xFF和0x01,是擴充套件的型別,接下來的兩個位元組0x00和0x01是擴充套件的長度,最後一個位元組是擴充套件資料的內容0x00。
IANA維護TLS引數的註冊。其中包括有效的TLS擴充套件型別。

TLS 1.2 Extension Types and Values

Extension Type Value Description
server_name 0 伺服器名稱
max_fragment_length 1 最大fragment長度協商
client_certificate_url 2 客戶端證書URL
trusted_ca_keys 3 Trusted CA keys
truncated_hmac 4 截斷的HMAC
status_request 5 證書狀態請求
user_mapping 6 User mapping
client_authz 7 客戶端認證
server_authz 8 伺服器認證
cert_type 9 證書型別
elliptic_curves 10 橢圓曲線密碼學
ec_point_formats 11
srp 12 SRP協議
supported_signature_algorithms 13 簽名演算法
use_srtp 14 SRTP的key建立
heartbeat 15 Heartbeat
application_layer-protocol_negotiation 16 協商應用層協議
status_request_v2 17 證書狀態請求,版本2
signed_certificate_timestamp 18
client_certificate_type 19 原始公鑰
server_certificate_type 20 原始公鑰
encrypt_then_mac 22 使用EtA代替AtE
extended_master_secret 23 安全重新協商(revisited)
session_ticket 35 Session tickets
renegotiation_info 65281 安全重新協商

New TLS Alert Messages

Alert Code Description
unsupported_extension 110 傳送者(總是客戶端)通知接收方,ServerHello訊息裡有不支援的擴充套件。永遠是fatal
certificate_unobtainable 111 傳送者(總是伺服器)通知接收方,不能讀取CertificateURL裡的證書(鏈)。可以是fatal
unrecognized_name 112 傳送者(總是伺服器)通知接收方,不認識ServerName擴充套件裡的名稱。可以是fatal
bad_certificate_status_response 113 傳送者(總是客戶端)通知接收方,收到了無效的證書狀態響應。永遠是fatal
bad_certificate_hash_value 114 傳送者(總是伺服器)通知接收方,證書hash與客戶端提供的不匹配。永遠是fatal

Server Name Indication

Virtual hosting技術是指同一臺機器上部署多個服務,可能使用一個IP地址。假如一個使用者在瀏覽器輸入 www.esecurity.ch,一個DNS找到IP地址是88.198.39.16的機器。瀏覽器建立到該機器的80埠的TCP連線,然後客戶端和伺服器使用HTTP交流。因為瀏覽器想訪問 www.esecurity.ch,客戶端就傳送帶host頭的HTTP請求訊息(Host: www.esecurity.ch),伺服器的機器就把這個HTTP請求傳給目標web伺服器。這樣,HTTP執行得很好。
考慮一下呼叫SSL/TLS,使用HTTPS代替了HTTP會發生什麼。在HTTP呢個被呼叫之前,必須建立SSL/TLS連線。它可能不清楚怎麼在一臺機器上區分不同的web服務。有很長時間,沒有類似的HTTP Host頭,於是,每個支援SSL/TLS的web服務只能使用唯一的IP地址。所以,要定義TLS伺服器名稱擴充套件,叫做server name indication (SNI),作用類似於HTTP Host header。使用SNI,客戶端一個客戶端可以傳送一個帶server_name擴充套件的ClientHello訊息,告訴伺服器,它想要連線的web服務的DNS主機名。這樣就不需要唯一的IP地址了。因為SNI是後來才加到TLS的,所以,還有很多產品不支援它。

Maximum Fragment Length Negotiation

一個SSL記錄的最大fragment長度是214。TLS也還是這樣。有時候,因為頻寬限制,需要較小長度的fragment。
max_fragment_length擴充套件(type等於1)可以由客戶端告訴伺服器,需要協商一個比較小的最大fragment長度。
實際的最大長度,由data屬性確定。值分別是1(代表29)、2(代表210)、3(代表211)和、4(代表212)。
該長度在一個TLS session期間有效,包括恢復的session,不能動態修改。

Client Certificate URL

代替了客戶端傳送的Certificate訊息。如果客戶端想使用這個機制,就在ClientHello訊息裡帶client_certificate_url擴充套件。
如果伺服器想支援這個機制,就在ServerHello訊息裡返回相同的擴充套件。客戶端和伺服器然後知道,在隨後的握手中,他們都可以使用客戶端證書URL機制。
使用這個機制的時候,客戶端可以傳送Certificate(型別是11)訊息,或者傳送CertificateURL(型別是21)訊息。從安全的觀點看,客戶端證書URL機制有一個問題,可能被引導到惡意網站。強烈建議,該機制在伺服器側生效之前,有一些保護機制,比如做一下資料內容檢查。不應該預設生效。

Trusted CA Keys

SSL/TLS握手的時候,伺服器傳送Certificate訊息時,不能預先知道客戶端可以接受的根CA。如果客戶端不接受伺服器提供的證書,就得重新握手。如果客戶端的ClientHello訊息包含了trusted_ca_keys,伺服器就能知道客戶端可以接受的根CA。伺服器返回的ServerHello訊息裡可以帶上空的trusted_ca_keys,告訴客戶端,它支援該擴充套件。客戶端支援的實際的證書,還是放在Certificate訊息裡。

Truncated HMAC

HMAC構造器的輸出,與使用的hash函式輸出一樣長(MD5是128位,SHA-1是160位,SHA-256是256位)。如果在一個受限制的環境裡使用HMAC構造器,HMAC的輸出會被截斷,比如是80位。此時要用truncated_hmac擴充套件。如果客戶端和伺服器都支援該機制,就可以使用截斷的HMAC代替完整的值。
注意,隻影響認證使用的HMAC計算,不影響TLS PRF裡的HMAC構造器(用於master secret和key計算)。
不推薦使用truncated_hmac。

Certificate Status Request

SSL/TLS握手的時候,收到證書的一方,會驗證證書的有效性。可以在證書撤銷清單(CRL)裡檢索,如果沒找到,就是有效的。或者使用線上證書狀態協議(OCSP)做驗證。
如果證書的接收方是一個受限的客戶端,CRL檢查和OCSP查詢太昂貴了。這種時候,伺服器可以替代客戶端做驗證。客戶端向伺服器發status_request訊號,說明它希望得到一些證書的狀態資訊,比如一個OCSP響應(這些附加資訊放在data屬性裡)。如果伺服器將提供請求的證書狀態資訊,它會返回一個CertificateStatus訊息(型別22)。
由於證書狀態資訊和OCSP密切相關,這個擴充套件也叫OCSP stapling。status_request擴充套件開啟的OCSP stapling只支援一個OCSP響應,能用於檢查一個伺服器證書的撤銷狀態。RFC 6961開始,有了新的擴充套件型別status_request_v2,支援多個OCSP響應。

User Mapping

這基於一個通用機制,用來在TLS握手時交換補充資料。這個機制和訊息流見下表。
客戶端和伺服器在他們能使用SupplementalData訊息傳送補充資料前,交換擴充套件的hello訊息。使用這個機制,當呼叫客戶端認證的時候,TLS擴充套件的user_mapping和SupplementalData格式的載荷能把使用者對映到他們的帳號。客戶端能在ClientHello訊息裡傳送該擴充套件,伺服器能在ServerHello訊息裡確認。然後,客戶端把使用者對映資料放在SupplementalData訊息裡發給伺服器。然後,伺服器解析和使用該資料。
The TLS handshake protocol supporting the exchange of supplemental application data

Authorization

TLS協議只提供授權(authorization),不提供認證(authentication)。
TLS擴充套件client_authz是指客戶端支援的authorization資料格式,和server_authz是指伺服器支援的authorization資料格式。該擴充套件可以在hello訊息裡傳送。類似使用者對映的機制,實際的authorization資料放在SupplementalData訊息裡。也可以不直接提供資料,而是提供一個URL做線上檢索。
可能有很多種authorization資料格式。比如屬性證書(attribute certificates)和安全斷言標記語言(SAML)。AC是一個數字簽名的資料結構,證明它持有的一些屬性(代替公鑰),它使用通用的subject屬性連結到一個公鑰證書。SAML斷言類似AC,但是語法不一樣。

Certificate Types

有兩種相互競爭的公鑰證書標準:X.509和(Open)PGP,SSL/TLS協議只支援X.509證書。X.509證書無效或者有更合適的非X.509證書的時候,可以使用擴充套件cert_type。
cert_type的data屬性是支援的證書型別列表,目前只支援X.509(0)和OpenPGP(1)。伺服器收到訊息,選擇證書需要的加密套件,或者選擇客戶端支援的證書型別,或者使用unsupported_certificate告警結束連線。對於第一種情況,伺服器必須編碼選擇的證書型別,放到ServerHello訊息的cert_type擴充套件內。
協商的證書型別也會影響Certificate訊息內的證書。如果協商使用X.509證書,證書就是這個型別的。如果協商使用OpenPGP證書,證書就是這個型別的。這時候,伺服器發給客戶端的CertificateRequest訊息(伺服器能接受的CA型別),必須是空的(OpenPGP證書是通訊實體釋出的,而不是CAs)。

Elliptic Curve Cryptography

ECC技術允許使用短key(安全級別相同)。TLS可以使用五種基於ECC的key交換演算法,他們都使用elliptic curve version of the Diffie-Hellman (ECDH) key交換演算法,他們的區別僅在於ECDH keys的使用壽命不同。第五種演算法是匿名的,不能用於認證。

  • ECDH_ECDSA:使用長期ECDH keys和ECDSA簽名的證書。伺服器的證書必須包含一個長期的ECDSA簽名的ECDH公鑰,不需要傳送ServerKeyExchange訊息。客戶端用與伺服器長期公鑰相同的橢圓曲線生成ECDH key對,使用ClientKeyExchange傳送自己的公鑰。然後,客戶端和伺服器執行ECDH key交換,生成pre master secret。
  • ECDHE_ECDSA:使用短暫的ECDH keys和ECDSA簽名的證書。伺服器的證書必須包含一個使用ECDSA簽名的ECDSA公鑰。伺服器使用ServerKeyExchange訊息傳送它的短暫的ECDH公鑰和相應的橢圓曲線規範。引數是使用ECDSA簽名的,使用伺服器證書裡的公鑰對應的私鑰。客戶端使用相同的橢圓曲線生成另一個ECDH key對,使用ClientKeyExchange訊息把公鑰發給伺服器。然後,客戶端和伺服器執行ECDH key交換,生成pre master secret。
  • ECDH_RSA:使用長期ECDH key和RSA簽名的證書。key交換演算法除了伺服器證書使用RSA做簽名以外,和ECDHE_ECDSA相同。
  • ECDHE_RSA:使用短暫的ECDH key和RSA簽名的證書。key交換演算法和ECDHE_ECDSA有以下不同:伺服器證書必須包含一個RSA公鑰的授權簽名,ServerKeyExchange訊息裡的簽名必須由對應的私鑰簽名,伺服器證書使用RSA簽名。
  • ECDH_anon:使用匿名的ECDH key交換,沒有認證。使用ServerKeyExchange和ClientKeyExchange交換ECDH公鑰。

ECDHE_ECDSA和ECDHE_RSA key交換演算法提供PFS,其他的不提供。五種演算法裡的每一個能被組合任何加密和hash函式形成加密套件。
有兩種TLS擴充套件使用ECC:elliptic_curves和ec_point_formats。當一個客戶端想支援ECC,就在ClientHello訊息裡包括一個或這兩個擴充套件。

  • elliptic_curves:客戶端通知伺服器,它能支援橢圓曲線。
  • ec_point_formats:客戶端通知伺服器,想壓縮某些曲線引數。實踐中不好用。

不管如何,這些擴充套件告訴伺服器選擇橢圓曲線,和決定是否壓縮,返回的選擇包含在ServerHello訊息內。然後,客戶端和伺服器就可以使用ECC了。

SRP Protocol

由於其易受MITM攻擊,Diffie-Hellman key交換必須總是做認證。使用密碼最簡單明瞭,所以有很多密碼認證的Diffie-Hellman key交換提案,這些提案很容易遭到字典攻擊。後來提出了加密的key交換(EKE)概念,至少有一方使用password加密一次性的公鑰,然後送給另一方,然後解密,用來協商共享的key。password不容易遭受字典攻擊,因為它是一個加密的隨機值。
secure remote password (SRP)協議就是這樣一個實現。TLS握手的時候,可以使用SRP協議實現客戶端認證。它補充了使用公鑰證書,預共享金鑰或Kerberos進行客戶端身份驗證。SRP協議是Diffie-Hellman key交換的一個變種,可以和任何加密和hash函式組合,形成加密套件。
如果客戶端想使用the協議執行key交換,它使用帶srp擴充套件的ClientHello訊息,如果伺服器也支援,就在ServerHello訊息裡返回這個擴充套件。客戶端和伺服器然後交換SPR的ServerKeyExchange和ClientKeyExchange訊息,計算master secret。
SRP的使用並不廣泛。

Signature Algorithms

有很多hash和簽名演算法。不同的客戶端支援的也不同。supported_signature_algorithms是可選的,客戶端用來告訴伺服器,它支援哪些hash和簽名演算法。如果不使用該擴充套件,伺服器假定支援SHA-1,並從客戶端提供的密碼套件中推斷出支援的簽名演算法。
hash演算法包括none (0), 26 MD5 (1), SHA-1 (2), SHA-224 (3), SHA-256 (4), SHA-384 (5)和SHA-512 (6)。
簽名演算法包括anonymous (0), RSA (1), 27 DSA (2)和ECDSA (3)。

Heartbeat

客戶端和伺服器都可以使用heartbeat擴充套件,確認之後,能互相傳送heartbeat請求/響應。heartbeat(訊息type是24)是又一個TLS子協議。
客戶端能傳送Heartbeat載荷,伺服器返回相同的載荷。

Application-Layer Protocol Negotiation

TLS之上,有兩種應用層協議的堆放策略:獨立埠的或者向上協商的。第一種策略需要每種應用層協議有獨立的埠,第二種策略需要應用層協議支援向上協商特性。如果一個TCP或者UDP埠上需要支援多個應用層協議,而這些協議又不支援向上協商特性,就可能在TLS握手結束的時候做應用層協議協商。這就需要application-layer protocol negotiation (ALPN),以前叫next protocol negotiation (NPN)。使用application_layer_protocol_negotiation擴充套件開啟ALPN,支援ALPN,443埠上的支援TLS的服務也能預設支援HTTP1.0,也允許協商其他應用層協議,比如HTTP2.0和SPDY3.3。客戶端可以在ClientHello訊息裡帶application_layer_protocol_negotiation擴充套件,提交它支援的應用層協議列表。伺服器然後在ServerHello訊息裡使用相同的擴充套件,告訴客戶端他的決定。

Certificate Transparency

Google有一個專案叫Certificate Transparency (CT),用來解決Internet PKI的一些問題。CT專案的一個機制是,允許CA把它釋出的每一個證書提交給公開的日誌服務,返回一個提交證明-signed certificate timestamp (SCT)-它能提供給依賴方。

Raw Public Keys

有時候,需要原生的公鑰,而不是複雜的公鑰證書。
在握手的時候,可以使用client_certificate_type和server_certificate_type,實現認證。
key可能是RSA, DSA或者ECDSA,

EtA Instead of AtE

目前的SSL/TLS,合適的認證和加密的組合是EtA,而不是AtE。有些實現支援改變認證和加密操作的順序,所以,可以在交換hello訊息時,用encrypt_then_mac擴充套件協商這個順序。
使用CBC加密以後,這個擴充套件是重要的。

Session Tickets

SSL握手協議可以恢復一個session。要呼叫這個1-RTT機制,伺服器需要儲存每個客戶端的session狀態。如果同時有大量的客戶端,會消耗伺服器的大量資源。可以把session狀態資訊當作一個session ticket發給客戶端,在以後的某個時刻返回伺服器以恢復session。這個思想有點類似HTTP cookies。
session_ticket擴充套件就是為此目的設計的,如果客戶端支援session tickets,它的ClientHello訊息裡帶上這個擴充套件發給伺服器,
如果客戶端不支援,該擴充套件為空。如果伺服器不支援,它會忽略該擴充套件。如果伺服器也支援該擴充套件,它返回一個帶空的session_ticket的ServerHello訊息(因為session狀態還沒確定)。伺服器在結束握手之前,傳送ChangeCipherSpec和Finished之前,傳送一個NewSessionTicket的訊息。
session ticket包含加密的session狀態,可能還有加密套件master secret和ticket生存時間(單位是秒)等。
客戶端接收到該訊息,它快取該session ticket。如果後來想恢復該session,就在ClientHello訊息裡帶上session_ticket擴充套件(不為空),伺服器解密和驗證該ticket,恢復session。如果伺服器想恢復該session,就在ServerHello訊息裡帶一個空的session_ticket,緊接著傳送一個NewSessionTicket的訊息。如果伺服器不想恢復該session,使用以前的辦法握手(沒有session_ticket擴充套件或者沒有NewSessionTicket訊息)。
The message flow of the TLS handshake protocol issuing a new session ticket

The message flow for an abbreviated TLS handshake protocol using a new session ticket

Secure Renegotiation

即使在使用renegotiation_info擴充套件的時候,人們仍然可以使用三次握手攻擊(triple handshake attack)實現重協商攻擊(renegotiation attack)。現在有了另一個擴充套件,extended_master_secret,他3確保每個TLS連線有一個不同的唯一的master key,這樣能防止未知的key共享攻擊(key-share attack)。

Summary

TLS 1.2的大部分擴充套件,都在ClientHello和ServerHello訊息內。
NewSessionTicket(type是4)、CertificateURL(type是21)、CertificateStatus(type是22)和SupplementalData(type是23)訊息是新的訊息型別。

Cipher Suites

TLS 1.2協議規範裡刪除了使用DES和IDEA技術的加密套件。保留的加密套件是採用3DES或者AES的塊加密或者採用RC4的流加密。
一些加密套件擴充套件了,以支援SHA-256。和以前的版本類似,TLS 1.2還支援預設的加密套件TLS_RSA_WITH_AES_128_CBC_SHA。

RFC 5116介紹了authenticated encryption with additional data (AEAD)演算法,定義了註冊這樣的演算法的介面。
AEAD對TLS 1.2很重要,對TLS 1.3更重要,因為TLS 1.3需要AEAD加密。AEAD演算法在一次密碼轉換中,組合了加密(機密性)和認證(完整性)。AEAD是密碼學研究中一個相對較新的領域,比如,可以使用塊加密產生AEAD加密。AEAD加密可以認證沒有加密的附加資料。這些附加資料可以是不能被預設加密的頭資訊。
在TLS裡,附加資訊包含TLSPlaintext結構或者TLSCompressed結構的順序號,type、version和length屬性。因為AEAD加密不包含separate MAC生成和驗證,它不需要respective keys。它只使用encryption keys(client_write_key和server_write_key),沒有MAC key。AEAD加密的輸出是一個密文,只能被相同的值解密。
有時候,使用公鑰太昂貴或者存在其他管理缺陷。這種時候,可能使用對稱key更有利,在通訊雙方之間提前共享,建立TLS連線。
TLS協議規定了基於preshared keys (PSKs)支援認證的三種加密套件集:

  • 第一種加密套件(PSK key交換演算法)只使用secret key演算法,用於受限環境
  • 第二種加密套件(DHE_PSK key交換演算法)使用PSK認證,暫時的Diffie-Hellman key交換
  • 第三種加密套件(RSA_PSK key交換演算法)伺服器使用基於RSA的認證,客戶端認證使用PSK