TLS原始碼解析-golang
概述
以golang 1.8.1版本為準。原始碼目錄:src/crypto/tlsRECORD協議
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 // 客戶端支援的壓縮方法,預設為null nextProtoNeg bool // 擴充套件NPN 是否支援次協議協商 serverName string // 擴充套件SNI 伺服器名稱,通常為域名,預設為目標地址主機名。支援SNI擴充套件需要的欄位。 ocspStapling bool // 擴充套件status_request 是否支援ocsp staping。全稱線上證書狀態檢查協議 (rfc6960),用來向 CA 站點查詢證書狀態 scts bool // 擴充套件SCT。是否支援SCT ticketSupported bool // 擴充套件Sessionticket.是否支援會話ticket sessionTicket []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=AEAD 0xC0 , 0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1. 2 Kx=ECDH Au=ECDSA Enc=AESGCM( 256 ) Mac=AEAD 0xC0 , 0x28 - ECDHE-RSA-AES256-SHA384 TLSv1. 2 Kx=ECDH Au=RSA Enc=AES( 256 ) Mac=SHA384 0xC0 , 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 |