0. 學習參考
RFC5389 中文翻譯 中文RFC RFC文檔 RFC翻譯 RFC中文版
RFC 5389:NAT 的會話遍歷實用程序 (STUN) --- RFC 5389: Session Traversal Utilities for NAT (STUN)
1. RFC 3489的演變
自 RFC 3489 發布以來的經驗發現,經典的 STUN 根本無法很好地工作,無法成為可部署的解決方案。通過傳統 STUN 學習的地址和端口有時可用于與對等體通信,有時則不能。Classic STUN 無法發現它是否實際上有效,并且在不起作用的情況下它不提供任何補救措施。此外,發現經典的 STUN 用于 NAT 類型分類的算法是錯誤的,因為許多 NAT 不能完全適應那里定義的類型。
Classic STUN 還存在一個安全漏洞——攻擊者可以在某些拓撲和約束下向客戶端提供不正確的映射地址,而這從根本上無法通過任何加密手段解決。盡管該規范仍然存在此問題,但現在通過使用使用 STUN 的更完整的解決方案來緩解這些攻擊。
2. STUN 業務概況
STUN 是一種客戶端 - 服務器協議,核心功能是幫助端點穿越 NAT,實現地址發現、連接性檢查和 NAT 綁定維持。以下是其操作概述的核心內容:
1. 協議架構與組件
-
實體角色:
- STUN 代理(Agent):分為客戶端和服務器,客戶端發送請求 / 指示并接收響應,服務器處理請求并返回響應。
- 網絡組件:包括私有網絡、NAT 設備和公共互聯網,客戶端通過 NAT 與服務器通信,服務器位于公共網絡側。
-
事務類型:
- 請求 / 響應事務:客戶端發送請求(如獲取反射地址),服務器返回響應,通過?96 位事務 ID?關聯請求與響應,確保唯一性和防重放攻擊。
- 指示事務:單向消息(如保活信號),不期待響應,用于維持 NAT 綁定活性。
2. STUN包 Binding 方法與反射地址獲取
-
核心功能:
- 通過?Binding 請求 / 響應?確定客戶端在 NAT 后的公網地址(反射地址)。客戶端發送請求,經 NAT 后服務器獲取其公網 IP 和端口,通過響應中的?XOR-MAPPED-ADDRESS?返回。
- 反射地址用途:用于 ICE 等 NAT 穿越方案,使端點能在公共網絡中建立連接。
-
流程細節:
- 客戶端發送 Binding 請求,源地址被 NAT 轉換為公網地址。
- 服務器接收請求,記錄源地址(反射地址),填入響應屬性并返回。
- 客戶端解析響應,獲取自身在公網的映射地址。
3. stun 多協議復用與區分機制
當 STUN 與其他協議(如 RTP、SIP)復用同一傳輸通道時,通過以下方式區分消息:
- 固定頭部特征:STUN 頭部前兩位為 0,Cookie 為固定值。
- FINGERPRINT 屬性:可選 CRC-32 校驗值,用于精確區分 STUN 與非 STUN 數據包。
4. stun 可選機制與安全擴展
認證機制:支持?短期憑證(帶外協商用戶名 / 密碼)和?長期憑證(Digest 挑戰 / 響應),通過?MESSAGE-INTEGRITY?屬性確保消息完整性。
DNS 發現:通過 STUN URI(如 stun://)和 SRV 記錄查找服務器地址,支持自動配置。
3. STUN 消息結構
3.1 消息整體架構與編碼規則
- 所有 STUN 消息必須以 20 字節的標頭開頭,后跟零個或多個屬性。STUN 標頭包含 STUN 消息類型、magic cookie、交易 ID 和消息長度。
- 每條 STUN 消息的最高有效 2 位必須為零,多路復用時,這可用于將 STUN 數據包與其他協議區分開來。
- 標頭的 STUN 固定部分后面是零個或多個屬性。每個屬性都經過 TLV(Type-Length-Value) 編碼。
3.2 固定頭部
- 二進制編碼:采用網絡字節序(大端序),遵循 [RFC 0791] 規范,數值常量默認十進制。
- 固定頭部 + 屬性擴展:消息由?20 字節固定頭部?和?可選屬性字段?組成,屬性采用 TLV(Type-Length-Value)格式,總長度需對齊 4 字節邊界。
STUN字段 | 長度 | 描述 |
---|---|---|
MSG TYPE | 2 字節 | 高 2 位為 0(區分其他協議),剩余 14 位分為: - 12 位?方法(Method):如 Binding(0x0001) - 2 位?類(Class):0b00 = 請求,0b01 = 指示,0b10 = 成功響應,0b11 = 錯誤響應 |
MSG length | 2 字節 | 不包含頭部的消息體長度(字節數),需為 4 的倍數(通過填充確保)。 |
Cookie | 4 字節 | 固定值?0x2112A442 ,用于區分 STUN 包與其他協議,兼容 RFC 5389 擴展檢測。 |
transcation ID | 12 字節 | 96 位隨機數,唯一標識事務: - 請求 / 響應事務中由客戶端生成,服務器回復攜帶 - 指示事務中由發送方生成,用于調試和防攻擊 |
示例:
- Binding 請求:類 = 0b00,方法 = 0x0001 → 消息類型 = 0x0001
- Binding 成功響應:類 = 0b10,方法 = 0x0001 → 消息類型 = 0x0101
3.3 屬性
格式:每個屬性由?2 字節類型、2 字節長度、可變長度值?組成,值需填充至 4 字節邊界(填充字節置 0)。
分類:
- 必須理解屬性(0x0000-0x7FFF):若不支持則無法處理消息,如?
MAPPED-ADDRESS
、ERROR-CODE
。 - 可選理解屬性(0x8000-0xFFFF):不支持時可忽略,如?
SOFTWARE
、ALTERNATE-SERVER
。
?
Type | 屬性名 | 含義 |
---|---|---|
0x0001 | MAPPED-ADDRESS | 客戶端在服務器端看到的 NAT 后的反射地址,包含 IP 地址和端口。用于幫助客戶端發現自己的公共 IP 地址和端口。僅用于兼容 RFC 3489 客戶端,新協議推薦使用?XOR-MAPPED-ADDRESS?防 NAT ALG 篡改。 |
0x0006 | USERNAME | 用于消息完整性檢查和認證過程的用戶名,標識消息完整性驗證中使用的用戶名,該值為可變長度的 UTF-8 編碼序列,且需經過OpaqueString 處理(基于 RFC 8265,非 SASLprep),用于短期 / 長期憑證的用戶名標識。 |
0x0008 | MESSAGE-INTEGRITY | 包含 STUN 消息的 HMAC-SHA1 哈希值(20 字節),用于確保消息在傳輸過程中未被篡改,保證消息的完整性和真實性。 |
0x0009 | ERROR-CODE | 用于錯誤響應消息,包含一個 300 到 699 范圍內的數字錯誤代碼,以及一個 UTF-8 編碼的文本短語,用于描述錯誤的具體信息。 |
0x000A | UNKNOWN-ATTRIBUTES | 當服務器收到包含其不識別屬性的 STUN 消息時,會在錯誤碼為 420 的錯誤響應中使用該屬性列出這些未知屬性的類型。 |
0x0014 | REALM | 可出現在請求和響應消息中,包含符合特定語法的文本,用于長期憑據認證。它是一個 UTF-8 編碼序列,長度少于 128 個字符,且經過 SASLprep 處理,出現該字段表示使用長期憑據認證方式。 |
0x0015 | NONCE | 由服務器生成的一個可變長度的不透明值,用于防止重放攻擊。客戶端在后續請求中需要包含相同的 NONCE 值,服務器通過檢查 NONCE 值確保消息的新鮮性和唯一性。需 UTF-8 編碼且經 SASLprep 處理。 |
0x0020 | XOR-MAPPED-ADDRESS | 與 MAPPED-ADDRESS 作用相同,不同點是 IP 地址經過了異或(XOR)處理。解決 ALG 篡改地址和端口的問題。 |
0x0024 | PRIORITY | 在 ICE(交互式連接建立)過程中,用于指示候選地址的優先級。客戶端會收集多個候選地址,每個地址都有對應的優先級,服務器或對端可根據該優先級決定優先使用哪個候選地址建立連接。RFC 8445 ICE 擴展定義。 |
0x0025 | USE-CANDIDATE | 用于通知對端立即使用指定的 ICE 候選地址對進行連接,跳過部分候選地址篩選和驗證過程,加速連接的建立。RFC 8445 ICE 擴展定義。 |
0x001C | MESSAGE-INTEGRITY-SHA256 | 與 MESSAGE-INTEGRITY 類似,但使用 SHA256 算法計算消息的 HMAC 哈希值,提供更高的安全性,用于保證消息的完整性。 |
0x001D | PASSWORD-ALGORITHM | 用于指定認證過程中所使用的密碼算法,告知對端采用何種加密算法對密碼進行處理和驗證。 |
0x001E | USERHASH | 對用戶名進行哈希處理后的值,用于在不直接傳輸明文用戶名的情況下進行用戶標識和認證,增強了用戶信息的安全性。 |
0x8002 | PASSWORD-ALGORITHMS | 列出服務器支持的所有密碼算法,客戶端可以根據這些信息選擇合適的算法進行認證。 |
0x8003 | ALTERNATE-DOMAIN | 提供一個備用的域名,用于在主域名不可用時作為替代,可能用于引導客戶端到備用的服務或資源。 |
0x8022 | SOFTWARE | 攜帶生成該 STUN 消息的軟件或設備的相關信息,如軟件名稱、版本號等,有助于網絡故障排查和統計分析。 |
0x8023 | ALTERNATE-SERVER | 提供備用的 STUN 或 TURN 服務器地址,當主服務器不可用時,客戶端可以嘗試連接這些備用服務器。 |
0x8028 | FINGERPRINT | 對消息計算的 CRC-32 值,用于快速驗證消息完整性。接收方重新計算 CRC-32 值并與該屬性值比較,若一致則消息未被篡改。 |
0x8029 | ICE-CONTROLLED | 在 ICE 連接建立過程中,標識一個端點處于受控(Controlled)角色,該端點需遵循控制者端點的決策來建立連接。RFC 8445 ICE 擴展定義。 |
0x802A | ICE-CONTROLLING | 在 ICE 連接建立過程中,標識一個端點處于控制(Controlling)角色,該端點負責協調和決定使用哪個候選地址對來建立連接。RFC 8445 ICE 擴展定義。 |
0x8000-0xFFFF | 可選的理解屬性 | 類型值在 0x8000 和 0xFFFF 之間的屬性是可選的理解屬性,這意味著這些屬性如果 STUN 代理不理解它們,則可以忽略它們。 |
3.4 STUN消息處理與邊界檢測
- 頭部校驗:接收方需驗證:
- 前 2 位為 0,Cookie 為?
0x2112A442
,消息長度合理。 - 方法是否支持,類是否匹配方法(如指示類不可用于某些擴展方法)。
- 前 2 位為 0,Cookie 為?
- 屬性解析:
- 按順序處理屬性,重復屬性僅處理首個(除非規范另有說明)。
- 必須理解屬性缺失或無法解析時,返回?
420 Unknown Attribute
?錯誤。
- 事務關聯:通過事務 ID 匹配請求與響應,指示消息無需響應但需校驗事務 ID 有效性。
3.5 舉例
Binding 請求(無認證)
- 頭部:消息類型 = 0x0001(請求),長度 = 0,魔術 Cookie=0x2112A442,事務 ID = 隨機 96 位值。
- 屬性:無(或含?
SOFTWARE
?等可選屬性)。
Binding 成功響應
- 頭部:消息類型 = 0x0101(成功響應),長度 = 屬性總長度。
- 屬性:必須包含?
XOR-MAPPED-ADDRESS
(含客戶端公網地址和端口)。
4. 基本協議程序
消息構造與傳輸規則(6.1-6.2)
"客戶端應以RTO(“重新傳輸超時”)的間隔開始重新傳輸STUN請求消息,每次重新傳輸后加倍。RTO是對往返時間(RTT)的估計,按照RFC 2988[RFC2988]中的描述計算,但有兩個例外。首先,RTO的初始值應該是可配置的(而不是RFC 2988中建議的3 s),并且應該大于500 ms。這種“應該”的例外情況是,當使用其他機制來推導擁塞閾值時(如ICE中為固定速率流定義的機制),或者在已知網絡容量的非互聯網環境中使用STUN。在固定線路接入鏈路中,建議使用500 ms的值。其次,RTO的值不應四舍五入到最接近的秒。相反,應保持1 ms的精度。與TCP一樣,建議使用Karn算法[KARN87]。當應用于STUN時,這意味著RTT估計值不應根據導致請求重新傳輸的STUN事務計算。"
1. 傳輸協議支持:
- UDP/DTLS-over-UDP: 不可靠傳輸,客戶端需重傳(初始 RTO≥500ms,指數退避,默認重傳 7 次);消息大小≤576 字節(IPv4)或 1280 字節(IPv6)。
- TCP/TLS-over-TCP:可靠傳輸,依賴 TCP 層重傳,客戶端超時默認 39.5s;支持多事務復用(同一服務器≤10 個并發),TLS 需驗證證書并禁用弱密碼套件。
- 協議復用:若與其他協議復用 TCP 連接,需通過成幀協議分割消息,知名端口(3478)的 STUN 服務無需成幀。
2. 消息接收與處理流程(6.3)
通用校驗步驟:
- 頭部驗證:檢查魔術 Cookie、消息長度、事務 ID 匹配及方法有效性,若啟用
FINGERPRINT
需校驗 CRC 值。 - 屬性解析:忽略未知可選屬性,若遇未知必須屬性,返回
420 Unknown Attribute
錯誤并列出屬性類型。
3. 按消息類處理邏輯:
- 請求(Request):驗證通過后生成響應:成功響應含
XOR-MAPPED-ADDRESS
(反射地址),錯誤響應含ERROR-CODE
(如 400/401);UDP 重傳請求需確保響應一致性(如緩存事務 ID)。 - 指示(Indication):無需響應,直接處理消息(如刷新 NAT 綁定),含未知必須屬性則丟棄。
- 響應(Response):客戶端校驗
MESSAGE-INTEGRITY
,失敗則按協議重傳(UDP)或終止(TCP)。
4. 錯誤處理與重試機制
錯誤碼分類:
- 3xx(重定向):如
300 Try Alternate
,客戶端需切換至ALTERNATE-SERVER
屬性指定的備用服務器。 - 4xx(客戶端錯誤):如
401 Unauthenticated
(認證失敗)、438 Stale Nonce
(憑證過期),需客戶端重試并攜帶新憑證。 - 5xx(服務器錯誤):如
500 Server Error
,客戶端可重試,但重傳次數≤4 次。
5. FINGERPRINT 機制
????????FINGERPRINT 機制是 STUN 的可選擴展,用于在?多協議復用同一傳輸地址(如 UDP 端口或 TCP 連接)時,準確區分 STUN 消息與其他協議的數據包,避免協議解析混淆。例如,當 STUN 與 RTP、SIP 等協議共享端口時,可通過該機制確保 STUN 消息被正確識別和處理。FINGERPRINT 機制不向后兼容 RFC 3489,并且不能在需要此類兼容性的環境中使用。
技術實現
屬性結構:FINGERPRINT 屬性為可選理解屬性(類型?0x8028
),需作為 STUN 消息的最后一個屬性,確保校驗覆蓋整個消息內容。屬性值為?CRC-32 校驗值,計算方式為:
- 對消息中除 FINGERPRINT 屬性本身外的所有字節計算 CRC-32
- CRC-32 生成多項式為
????????將多項式的各項系數轉換為二進制(僅保留最高位至最低位的非零位),其對應的?32 位二進制掩碼?為:?
100000100110000010001101101100111
(共 32 位,首位為 1)。) - 將計算結果與固定值?
0x5354554E
("STUN" 的 ASCII 碼異或值)進行異或運算,得到最終屬性值。
校驗流程:
- 接收方收到消息后,先剝離 FINGERPRINT 屬性,重新計算剩余內容的 CRC-32,并異或?
0x5354554E
。 - 將計算結果與屬性值對比,若不一致則判定為非 STUN 消息或被篡改的消息,直接丟棄。
6. DNS Discovery of a Server?機制
1. 核心功能與用途
DNS 發現機制是 STUN 的可選擴展,用于幫助客戶端通過 DNS 協議動態獲取 STUN 服務器的 IP 地址和端口號,避免硬編碼服務器地址,提升協議的靈活性和可維護性。適用于客戶端無法預先知曉服務器地址的場景(如公共互聯網環境)。
2. STUN URI 方案
URI 格式:
stun://
:用于普通 UDP/TCP 連接的 STUN 服務器(非加密)。stuns://
:用于 TLS-over-TCP 或 DTLS-over-UDP 連接的加密 STUN 服務器。
語法規則:
- 示例:
stun:stun.example.com:3478
?或?stuns:stun-secure.example.com:5349
。- 若 URI 包含 IP 地址(如?
stun:192.168.1.1:3478
),客戶端直接連接;若包含域名(如?stun.example.com
),需通過 DNS 解析。
3. DNS 解析流程
3.1 SRV 記錄優先
客戶端首先查詢?DNS SRV 記錄,格式為:
<scheme>
:stun
?或?stuns
(對應 URI 方案)。<protocol>
:udp
?或?tcp
(傳輸協議)。- 示例:查詢?
_stun._udp.example.com
?獲得 UDP 協議的 STUN 服務器地址和端口。- SRV 記錄返回優先級(Priority)、權重(Weight)和目標地址(Target),客戶端按優先級和權重選擇服務器。
_<scheme>._<protocol>.example.com
3.2 直接查詢 A/AAAA 記錄
若 SRV 記錄不存在,客戶端查詢域名的?A 記錄(IPv4)?或?AAAA 記錄(IPv6),使用默認端口:
- UDP/TCP:3478。
- TLS/DTLS:5349。
雙棧客戶端需同時查詢 A 和 AAAA 記錄,嘗試所有地址。
4. 傳輸協議與端口
默認端口:
協議類型 | 普通連接(stun://) | 加密連接(stuns://) |
---|---|---|
UDP/TCP | 3478 | 不適用 |
TLS-over-TCP | 不適用 | 5349 |
DTLS-over-UDP | 不適用 | 5349 |
端口復用:服務器可在同一端口支持多種協議(如 UDP 和 DTLS 共用 5349 端口),通過初始消息類型區分。
7. 加密認證與消息完整性機制
1. 核心目標與機制概述
STUN 定義兩種認證與消息完整性機制,用于防范中間人攻擊、消息篡改和重放攻擊,確保通信雙方身份可信及數據完整。
- 適用場景:
- 短期憑證:臨時會話(如 ICE 連接)。
- 長期憑證:固定用戶身份(如企業認證)。
- 關鍵屬性:
USERNAME
(用戶名)、MESSAGE-INTEGRITY
(HMAC 哈希)、NONCE
(防重放隨機值)。
2. 短期憑證機制(Short-Term Credential Mechanism)
2.1 核心流程與機制
-
帶外密鑰協商
- 客戶端與服務器通過非 STUN 協議的安全渠道(例如 SIP 信令、WebRTC 信令)提前共享短期有效的用戶名(
USERNAME
)和密碼(PASSWORD
)。 - 憑證時效性:憑證僅在特定時間段或會話周期內有效(如媒體會話期間),超時后自動失效,降低泄露風險。
- 客戶端與服務器通過非 STUN 協議的安全渠道(例如 SIP 信令、WebRTC 信令)提前共享短期有效的用戶名(
-
消息完整性校驗
- HMAC 算法:使用HMAC-SHA1或HMAC-SHA256算法計算消息的完整性校驗值,具體取決于協商的算法。
- 屬性攜帶:
- 客戶端請求中必須包含:
USERNAME
屬性(UTF-8 編碼的用戶名,經 OpaqueString 處理)。MESSAGE-INTEGRITY
(HMAC-SHA1 結果,20 字節)或MESSAGE-INTEGRITY-SHA256
(HMAC-SHA256 結果,≥16 字節且為 4 的倍數)。
- 服務器響應中需包含對應的完整性屬性(但不包含
USERNAME
,避免明文傳輸)。
- 客戶端請求中必須包含:
-
密鑰生成規則
- 密鑰直接由密碼的 UTF-8 字節序列生成:
key=OpaqueString(password) - 無需復雜的挑戰響應流程,直接通過預共享密鑰計算 HMAC 值,提升認證效率。
- 密鑰直接由密碼的 UTF-8 字節序列生成:
2.1 關鍵處理邏輯
客戶端發送請求: 構造 STUN 消息時,將USERNAME
和完整性屬性附加到消息中。例如,在 Binding 請求中,客戶端通過帶外獲取的用戶名和密碼生成 HMAC 值,填入MESSAGE-INTEGRITY-SHA256
屬性。
服務器驗證流程:
- 提取
USERNAME
和完整性屬性,驗證用戶名是否在有效期內。- 如果消息不同時包含消息完整性和用戶名屬性:
- 如果消息是請求,則服務器必須以錯誤響應拒絕該請求。此響應必須使用錯誤代碼400(錯誤請求)。
- 如果消息是一個指示,則代理必須以靜默方式放棄該指示。
- 如果消息不同時包含消息完整性和用戶名屬性:
- 使用相同的密碼和算法重新計算 HMAC 值,與消息中的屬性值對比:
- 一致:認證通過,代理將繼續處理請求或指示。服務器生成的任何響應都必須包含MESSAGE-INTEGRITY屬性,該屬性使用用于驗證請求的密碼進行計算。響應不能包含USERNAME屬性。
- 不一致:返回
401 Unauthenticated
錯誤,拒絕請求。 - 如果消息是一個指示,則代理必須以靜默方式放棄該指示。
客戶端收到答復
客戶端在響應中查找MESSAGE-INTEGRITY屬性。如果存在,客戶端將使用其用于請求的相同密碼,按照第15.4節中的定義計算響應上的消息完整性。如果結果值與MESSAGE-INTEGRITY屬性的內容匹配,則認為響應已通過身份驗證。如果值不匹配,或者缺少消息完整性,則必須丟棄響應,就像從未收到響應一樣。這意味著重新傳輸(如果適用)將繼續。
?
3. 長期憑證機制
長期憑證機制(Long-Term Credential Mechanism)是一種基于預共享密鑰的認證方式,適用于需要長期固定身份驗證的場景(如企業用戶、服務訂閱者)。其核心是通過挑戰 / 響應流程和密碼算法協商,確保通信雙方身份可信及消息完整性,同時防范重放攻擊和算法降級攻擊。
1. 憑證來源與特性
- 預共享憑證: 客戶端與服務器通過帶內或帶外渠道預先配置用戶名(
USERNAME
)和密碼(PASSWORD
),憑證長期有效(如用戶注冊時生成),直至用戶主動修改或服務終止。 - 適用場景: 企業網絡、需要用戶登錄的服務(如 VoIP 運營商),或需長期維護信任關系的通信場景。
2. 認證流程:挑戰 / 響應模式
第一步:未認證請求(首次交互)
- 客戶端發送不含認證屬性的 STUN 請求(如 Binding 請求)。
- 服務器返回 **
401 Unauthenticated
錯誤響應 **,附帶:REALM
屬性:認證域(如example.com
),指示用戶使用的憑證范圍。NONCE
屬性:服務器生成的防重放隨機值,包含安全特征位(如支持的密碼算法標識)。
第二步:攜帶憑證的二次請求
客戶端收到挑戰后,生成認證信息:
- 用戶名處理:
- 明文
USERNAME
或哈希值USERHASH
(SHA-256(USERNAME:REALM)
,避免明文傳輸)。
- 明文
- 密鑰生成:
- 根據協商的密碼算法(如 MD5、SHA-256),生成 HMAC 密鑰:
- 完整性校驗:
- 使用密鑰計算消息的
MESSAGE-INTEGRITY
或MESSAGE-INTEGRITY-SHA256
,覆蓋請求頭部、REALM
、NONCE
等屬性。
- 使用密鑰計算消息的
客戶端重新發送請求,包含USERNAME
/USERHASH
、REALM
、NONCE
及完整性屬性。
第三步:服務器驗證
服務器校驗:
NONCE
有效性:檢查是否為近期生成,未被篡改(通過安全特征位匹配協商的算法)。- HMAC 一致性:使用相同算法和密鑰重新計算 HMAC,與請求中的完整性屬性對比。
驗證通過:返回成功響應;失敗:返回401
或438 Stale Nonce
(NONCE 過期,需重試)。
3. 長期憑證 安全增強機制
(1) 防重放與防降級攻擊
-
NONCE 的安全特征位:
-
NONCE 前綴包含
obMatJos2
+ 安全特征位編碼(如Bit 0
表示支持密碼算法協商),防止中間人刪除強算法屬性(如強制使用 MD5)。 -
若客戶端發現響應中
PASSWORD-ALGORITHMS
與 NONCE 特征位矛盾,終止會話。
-
(2) 密碼算法協商
-
算法列表: 服務器通過
PASSWORD-ALGORITHMS
屬性聲明支持的算法(如MD5
、SHA-256
),客戶端通過PASSWORD-ALGORITHM
選擇其一。 -
推薦算法:
-
優先使用
SHA-256
,因其抗碰撞性優于 MD5;MD5 僅用于兼容舊系統。
-
(3) 用戶名匿名化
-
使用
USERHASH
替代USERNAME
:避免在網絡中傳輸明文用戶名,降低身份泄露風險。
4. 消息完整性計算示例
假設使用 SHA-256 算法:
服務器收到后,用相同密鑰和算法重新計算,驗證是否一致。
5. 與短期憑證機制的對比
特性 | 長期憑證機制 | 短期憑證機制 |
---|---|---|
憑證生命周期 | 長期有效(用戶級) | 短期有效(會話級) |
認證流程 | 挑戰 / 響應(需 2 次消息往返) | 直接攜帶憑證(1 次往返) |
安全強度 | 高(支持算法協商 + 防降級) | 中(依賴帶外渠道安全性) |
適用場景 | 企業認證、固定用戶 | 臨時會話、實時通信 |
總結
長期憑證機制通過預共享密鑰和挑戰響應流程,為需要長期信任關系的場景提供了可靠的認證方案。REALM、USERNAME、 NONC(領域 - 身份 - 會話)其核心優勢在于支持密碼算法協商、防重放攻擊和用戶名匿名化,同時通過 NONCE 的安全特征位抵御中間人攻擊。盡管流程較短期憑證復雜,但適用于對安全性要求較高的企業級部署,是 STUN 協議在身份認證領域的重要擴展。
涉及相關知識
Karn 算法
Karn 算法是用于 TCP(傳輸控制協議)中往返時間(RTT,Round-Trip Time)測量和估計的一種算法。它主要用于解決在 TCP 重傳時如何準確估計 RTT 的問題。
Karn 算法的核心思想是:在數據包重傳時,不使用重傳后接收到的 ACK 來更新 RTT 估計。具體來說,當數據包被重傳后,接收到的 ACK 不能用于測量 RTT,因為無法確定該 ACK 是對原始傳輸還是重傳的響應。
Karn 算法的具體步驟
-
初始傳輸:當一個數據包首次傳輸時,記錄發送時間,并啟動超時計時器。
-
接收 ACK:如果在超時時間內接收到 ACK,使用該 ACK 來更新 RTT 估計。
-
超時重傳:如果超時時間到達且未接收到 ACK,重傳數據包,并重置超時計時器。
-
處理重傳后的 ACK:
-
當接收到 ACK 時,如果該 ACK 確認的是重傳的數據包,則不使用該 ACK 來更新 RTT 估計。
-
如果該 ACK 確認的是原始傳輸的數據包,則可以使用該 ACK 來更新 RTT 估計。
-
Karn 算法的優點
-
提高 RTT 估計的準確性:避免了因重傳導致的 RTT 樣本不準確的問題,從而提高了 RTT 估計的準確性。
-
穩定性:通過避免使用重傳后的 ACK 來更新 RTT 估計,減少了因網絡抖動或丟包導致的 RTT 估計波動。
Karn 算法的限制
-
無法處理所有情況:在某些情況下,例如網絡中存在重復 ACK 或部分確認時,Karn 算法可能無法完全避免 RTT 估計的不準確。
-
依賴于其他機制:Karn 算法通常與其他機制(如 duplicated ACK 檢測)結合使用,以進一步提高 RTT 估計的準確性。
Karn 算法的總結
Karn 算法通過避免使用重傳后的 ACK 來更新 RTT 估計,提高了 RTT 估計的準確性。這對于 TCP 的擁塞控制和流量控制非常重要,因為它可以更準確地反映網絡的實際延遲情況,從而更好地適應網絡條件的變化。
HMAC
在 RFC 8489 中,HMAC(Hash-Based Message Authentication Code)用于實現?消息完整性校驗?和?身份認證,確保 STUN 消息在傳輸中未被篡改,并驗證通信方身份。以下是文檔中關于 HMAC 計算的核心內容:
1. 核心用途與算法支持
用途:
- 驗證消息完整性:確保消息在傳輸過程中未被中間人篡改。
- 認證通信方:通過共享密鑰(密碼)證明發送方身份。
支持的算法:
- HMAC-SHA1(20 字節,用于?
MESSAGE-INTEGRITY
?屬性)。 - HMAC-SHA256(≥16 字節,用于?
MESSAGE-INTEGRITY-SHA256
?屬性)。 - 長期憑證機制中支持?MD5?等算法(通過?
PASSWORD-ALGORITHM
?屬性協商)。
特性 | SHA1 | SHA256 |
---|---|---|
哈希長度 | 160 位(20 字節) | 256 位(32 字節) |
抗碰撞性 | 已被證明存在碰撞風險,不安全 | 尚未被攻破,符合現代安全標準 |
文檔推薦性 | 僅用于兼容舊版本 | 優先使用,尤其是敏感場景 |
防降級攻擊 | 可被中間人強制使用(需額外防護) | 通過Nonce 安全特征位抵制降級攻擊 |
2. 短期憑證機制中的 HMAC 計算
2.1 密鑰生成
????????密鑰來源: 密鑰為客戶端與服務器通過帶外協商的?密碼(Password),經 UTF-8 編碼后直接使用,不進行額外處理:key=OpaqueString(password),OpaqueString
?指直接使用字節序列,不進行 Unicode 規范化(RFC 8265)。
2.2 輸入數據范圍
計算對象:除?MESSAGE-INTEGRITY
/MESSAGE-INTEGRITY-SHA256
?屬性本身外的整個 STUN 消息。
步驟:
- 構造消息時,先預留完整性屬性位置(長度字段設為 0,值設為 dummy)。
- 計算 HMAC 值,覆蓋頭部、其他屬性及預留字段。
- 將計算得到的 HMAC 值填入屬性,并更新消息長度字段。
2.3 示例公式
若使用 HMAC-SHA256:
結果需至少 16 字節,且為 4 的倍數(如 32 字節)。
3. 長期憑證機制中的 HMAC 計算
3.1 密鑰生成(以 MD5 為例)
步驟:
- 將?用戶名(Username)、域(Realm)、密碼(Password)?拼接為字符串:
username:realm:password
。 - 計算拼接字符串的?MD5 哈希,生成 16 字節密鑰:
算法協商: 通過?PASSWORD-ALGORITHMS
(服務器支持列表)和?PASSWORD-ALGORITHM
(客戶端選擇)指定算法(如 SHA-256)。
3.2 輸入數據與計算邏輯
與短期憑證類似,但需包含?NONCE
、REALM
?等認證相關屬性。
防重放機制: 服務器生成的?NONCE
?包含安全特征位,確保 HMAC 計算與當前會話綁定,防止重放攻擊。
4. 關鍵處理規則
4.1 消息長度調整
計算 HMAC 前,需將消息長度字段臨時設置為?包含完整性屬性占位符的長度,計算完成后再更新為實際值。示例:
- 原始消息長度為 L(不含完整性屬性),占位符長度為 4(類型 + 長度字段),臨時長度設為 L+4,最終填入 L+4+N(N 為 HMAC 值長度)。
4.2 響應中的 HMAC 回顯
服務器響應必須包含與請求匹配的完整性屬性(如請求使用?MESSAGE-INTEGRITY-SHA256
,響應也需包含該屬性)。
響應中?不包含?USERNAME
,避免明文傳輸用戶身份信息。
5. 安全與兼容性
防降級攻擊: 通過?NONCE
?中的安全特征位(如?Password algorithms
?位)標識支持的算法,防止中間人強制使用弱算法(如 MD5)。
兼容性:
- 舊版本客戶端可能僅支持 HMAC-SHA1,需通過協議協商兼容。
- 新版本推薦使用 HMAC-SHA256,滿足更高安全要求。