1. 程式人生 > >TLS原始碼解析-golang

TLS原始碼解析-golang

概述

以golang 1.8.1版本為準。原始碼目錄:src/crypto/tls

RECORD協議

record型別

const (recordTypeChangeCipherSpec recordType = 20  // changecipherspec表明傳送端已取得用以生成連線引數的足夠資訊。內容隨密碼套件不同recordTypeAlert            recordType = 21  // alert協議型別recordTypeHandshake        recordType = 22  // 握手協議型別recordTypeApplicationData  recordType = 23  
// 應用資料協議型別)

record head長5個位元組

|--record type--|--version--|--data length--|

record type: 1個位元組

version:        2個位元組

data length:  2個位元組  最大值16KB

一條record的長度是可變的, 參考: https://blog.csdn.net/liujiyong7/article/details/65632819

record是TLS 加解密的最小單元,至少要收到一個完整的record,才能加解密。

record 協議會執行以下動作

1. 分片,將應用層的資料進行分片

2. 生成序列號,防重放

3. 壓縮, 可選,握手協議會進行協商,但是不建議壓縮

4. 算HMAC, 計算資料HMAC,防止篡改,偽造

5. 發給tcp/ip,    下層協議,也可以是udp

HANDSHAKE協議

第一次Read或Write方法會自動呼叫Handshake()方法

完整的握手

ClientHello

type clientHelloMsg struct {raw                          []byte      // 原始資料vers                         uint16      // 協議版本,指示客戶端支援的最大協議版本random                       []byte      // 隨機數 32位元組sessionId                    []byte      
// 會話ID,第一次為空,服務端藉助會話ID恢復會話,需要伺服器端快取。cipherSuites                 []uint16    // 客戶端支援的加密套件列表compressionMethods           []uint8     // 客戶端支援的壓縮方法,預設為nullnextProtoNeg                 bool        // 擴充套件NPN 是否支援次協議協商serverName                   string      // 擴充套件SNI 伺服器名稱,通常為域名,預設為目標地址主機名。支援SNI擴充套件需要的欄位。ocspStapling                 bool        // 擴充套件status_request 是否支援ocsp staping。全稱線上證書狀態檢查協議 (rfc6960),用來向 CA 站點查詢證書狀態scts                         bool        // 擴充套件SCT。是否支援SCTticketSupported              bool        // 擴充套件Sessionticket.是否支援會話ticketsessionTicket                []uint8     // 擴充套件Sessionticket 會話ticket,區別於sessionId的新的會話恢復機制,這種機制不需要伺服器端快取。signatureAndHashes           []signatureAndHash  // 擴充套件SignatureAlgorithms 簽名和雜湊演算法secureRenegotiation          []byte      // 擴充套件RenegotiationInfo 如果請求重新協商,就會發起一次新的握手。secureRenegotiationSupported bool        // 擴充套件RenegotiationInfo 是否支援renegotiation_info擴充套件 安全重新協商alpnProtocols                []string    // 擴充套件ALPN 應用層協議協商。}

常用的擴充套件

支援ECC需要兩個擴充套件 ellipic curve,point formats

SNI擴充套件用來實現安全虛擬主機。單個伺服器可能配有多個證書,服務端使用SNI來區分請求使用的是哪個證書。

SPDY使用NPN擴充套件協商使用何種應用層協議

HTTP2的協議協商過程使用ALPN擴充套件

ALPN是由客戶端給伺服器傳送一個協議清單,由伺服器來選擇一個。NPN正好相反

加密套件

使用openssl ciphers -V | column -t 檢視本機支援的cipher suite列表。如下所示:

0xC0,0x30  -  ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH        Au=RSA    Enc=AESGCM(256)    Mac=AEAD0xC0,0x2C  -  ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH        Au=ECDSA  Enc=AESGCM(256)    Mac=AEAD0xC0,0x28  -  ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH        Au=RSA    Enc=AES(256)       Mac=SHA3840xC0,0x24  -  ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH        Au=ECDSA  Enc=AES(256)       Mac=SHA384

Kx表示金鑰交換演算法 Au表示認證演算法 Enc表示加密演算法 Mac表示訊息認證碼演算法

每一種cipher suite由一個uint16整數標示

golang的預設cipher suites (如果監測到AES-GSM硬體,會優先提供aes-gcm的加密套件)

topCipherSuites = []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,}

EC引數填充

supportedCurves的值預設填充以下引數:
var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521} // 23 24 25 29
supportedPoints 預設為0 不壓縮

ServerHello

訊息的意義是將伺服器選擇的引數傳回客戶端,結構與clientHello相似,每個欄位只包含一個選項

type serverHelloMsg struct {raw                          []byte      // 原始資料vers                         uint16      // 服務端選擇的版本號 通常為client server都支援的版本中最高的。 common.go:mutualVersion()random                       []byte      // 服務端生成的隨機數  32位元組sessionId                    []byte      //cipherSuite                  uint16      // 服務端選擇的加密套件  通常為client server都支援的套件中,最靠前的。所以套件的順序是有講究的。compressionMethod            uint8       // 選擇的壓縮方法 只會選擇不壓縮。如果客戶端不支援不壓縮,會報錯nextProtoNeg                 bool        // client支援,則server支援nextProtos                   []string    // 服務端支援的應用層協議ocspStapling                 bool        //scts                         [][]byte    // 簽名的證書時間戳?ticketSupported              bool        //secureRenegotiation          []byte      //

相關推薦

TLS原始碼解析-golang

概述以golang 1.8.1版本為準。原始碼目錄:src/crypto/tlsRECORD協議record型別const (recordTypeChangeCipherSpec recordType = 20  // changecipherspec表明傳送端已取得用以生成

SSL/TLS深度解析--OpenSSL的基本使用

with xiv ppc mes fall ble 默認 bcg otl 摘要算法 [root@localhost ~]# openssl dgst -help #默認sha256 Usage: dgst [options] [file...] file..

SSL/TLS深度解析--OpenSSL s_client測試子命令

gad images record .com dmv none block http warning #下載第三方的最新的PEM(privacy-enhanced mail)格式的可信證書庫 [root@localhost ~]# wget --no-check-certi

Netty進階:Futrue&Promise原始碼解析

文章目錄 1. Future&Promise 2. AbstractFuture 3.Completefuture 4.Channelfuture&Completechannel

大資料基礎(1)zookeeper原始碼解析

五 原始碼解析   public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING;}zookeeper伺服器狀態:剛啟動LOOKING,follower是FOLLOWING,leader是LEADING,observer是

Android框架原始碼解析之(四)Picasso

這次要分析的原始碼是 Picasso 2.5.2 ,四年前的版本,用eclipse寫的,但不影響這次我們對其原始碼的分析 地址:https://github.com/square/picasso/tree/picasso-parent-2.5.2 Picasso的簡單使用

Android框架原始碼解析之(三)ButterKnife

注:所有分析基於butterknife:8.4.0 原始碼目錄:https://github.com/JakeWharton/butterknife 其中最主要的3個模組是: Butterknife註解處理器https://github.com/JakeWharton/

Android框架原始碼解析之(二)OKhttp

原始碼在:https://github.com/square/okhttp 包實在是太多了,OKhttp核心在這塊https://github.com/square/okhttp/tree/master/okhttp 直接匯入Android Studio中即可。 基本使用:

Android框架原始碼解析之(一)Volley

前幾天面試CVTE,HR面掛了。讓內部一個學長幫我查看了一下面試官評價,發現二面面試官的評價如下: 廣度OK,但缺乏深究能力,深度與實踐不足 原始碼:只能說流程,細節程式碼不清楚,retrofit和volley都是。 感覺自己一方面:自己面試技巧有待提高吧(框

HashMap原始碼解析(JDK8)

前言 這段時間有空,專門填補了下基礎,把常用的ArrayList、LinkedList、HashMap、LinkedHashMap、LruCache原始碼看了一遍,List相對比較簡單就不單獨介紹了,Map準備用兩篇的篇幅,分別介紹HashMap和(LruCache+LinkedHa

原始碼解析--Long、long型別的比較遇到的問題

Long、long型別的比較遇到的問題: 1、long 是基本型別 Long是物件型別。 public static void main(String[] args) { Long A = 127l; Long B = 127l; long C = 127; l

CopyOnWriteArrayList實現原理以及原始碼解析

CopyOnWriteArrayList實現原理以及原始碼解析 1、CopyOnWrite容器(併發容器) Copy-On-Write簡稱COW,是一種用於程式設計中的優化策略。 其基本思路是,從一開始大家都在共享同一個內容,當某個人想要修改這個內容的時候,才

LinkedList實現原理以及原始碼解析(1.7)

LinkedList實現原理以及原始碼解析(1.7) 在1.7之後,oracle將LinkedList做了一些優化, 將1.6中的環形結構優化為了直線型了連結串列結構。 1、LinkedList定義: public class LinkedList<E>

ArrayList實現原理以及原始碼解析(補充JDK1.7,1.8)

ArrayList實現原理以及原始碼解析(補充JDK1.7,1.8) ArrayList的基本知識在上一節已經討論過,這節主要看ArrayList在JDK1.6到1.8的一些實現變化。 JDK版本不一樣,ArrayList類的原始碼也不一樣。 1、ArrayList類結構:

ArrayList實現原理以及原始碼解析(JDK1.6)

ArrayList實現原理以及原始碼解析(JDK1.6) 1、ArrayList ArrayList是基於陣列實現的,是一個動態陣列,其容量能自動增長,類似於C語言中的動態申請記憶體,動態增長記憶體。 ArrayList不是執行緒安全的,只能用在單執行緒環境下。

ConcurrentHashMap實現原理以及原始碼解析

ConcurrentHashMap實現原理以及原始碼解析 ConcurrentHashMap是Java1.5中引用的一個執行緒安全的支援高併發的HashMap集合類。 1、執行緒不安全的HashMap 因為多執行緒環境下,使用Hashmap進行put操作會引起死迴圈

Java併發程式設計高階技術-高效能併發框架原始碼解析與實戰(資源同步)

第1章 課程介紹(Java併發程式設計進階課程) 什麼是Disruptor?它一個高效能的非同步處理框架,號稱“單執行緒每秒可處理600W個訂單”的神器,本課程目標:徹底精通一個如此優秀的開源框架,面試秒殺面試官。本章會帶領小夥伴們先了解課程大綱與重點,然後模擬千萬,億級資料進行壓力測試。讓大

PackageManagerService 原始碼解析

一.SystemServer建立PackageManagerService     省略 二.PackageManagerService 建構函式  2.1 Settings mSettings = new Settings(mPacka

Java中compareTo用法及原始碼解析

最近遇到一個問題,在日期比較的時候,很麻煩,因為日期比較沒有大於等於,只有大於或者小於,這就導致在比較時間的時候特別麻煩,而且還要由string轉成date格式才能比較,下面是我使用compareTo比較時間字串的程式碼: String putStartTime = Date

大資料基礎之Quartz(1)簡介、原始碼解析

一簡介 官網 http://www.quartz-scheduler.org/ What is the Quartz Job Scheduling Library? Quartz is a richly featured, open source job scheduling libra