高級
Peer Connection 節點連接
了解閃電網路節點如何建立加密連接,包括 BOLT 8 Noise Protocol 握手和訊息加密。
10 分鐘
連接概述
閃電網路節點之間的通訊使用 BOLT 8 定義的加密協議,基於 Noise Protocol Framework。 每個連接都經過身份驗證和加密,確保通訊安全和節點身份驗證。
Noise_XK: 閃電網路使用 Noise_XK 握手模式,發起者知道回應者的公鑰, 但回應者在握手過程中才得知發起者身份。
節點身份
Node Identity: 節點公鑰 (Node Public Key): • 格式:secp256k1 壓縮公鑰(33 bytes) • 範例:02778f4a4a...(66 hex 字元) 用途: • 唯一識別節點 • 加密通訊(ECDH) • 簽署訊息 • 驗證通道公告 節點地址 (Node Address): • 連接字串格式:<node_pubkey>@<host>:<port> • 範例: - [email protected]:9735 - [email protected]:9735 • 預設端口:9735(主網)、19735(測試網) 地址類型 (Address Types): • IPv4:常規 IP 地址 • IPv6:IPv6 地址 • Torv3:Tor 洋蔥地址(隱私) • DNS:域名解析 • WebSocket:瀏覽器連接(某些實現)
Noise Protocol 握手
BOLT 8 Handshake (Noise_XK):
Message Flow:
Initiator (I) Responder (R)
| |
|---- Act One (50 bytes) -------->|
| |
|<--- Act Two (50 bytes) ---------|
| |
|---- Act Three (66 bytes) ------>|
| |
| [Handshake complete] |
|<==== Encrypted Messages =======>|
Act One (Initiator -> Responder):
• 50 bytes 結構:
- version: 1 byte(0x00)
- ephemeral_key: 33 bytes(發起者臨時公鑰)
- tag: 16 bytes(ChaCha20-Poly1305 MAC)
• 發起者步驟:
1. 生成臨時金鑰對 (e_i, E_i)
2. 計算 ECDH:es = E_i * rs(回應者靜態公鑰)
3. 衍生加密金鑰
4. 加密並發送
Act Two (Responder -> Initiator):
• 50 bytes 結構:
- version: 1 byte(0x00)
- ephemeral_key: 33 bytes(回應者臨時公鑰)
- tag: 16 bytes(ChaCha20-Poly1305 MAC)
• 回應者步驟:
1. 解密 Act One,驗證
2. 生成臨時金鑰對 (e_r, E_r)
3. 計算 ECDH:ee = E_r * E_i
4. 加密並發送
Act Three (Initiator -> Responder):
• 66 bytes 結構:
- version: 1 byte(0x00)
- encrypted_pubkey: 49 bytes(發起者靜態公鑰,加密)
- tag: 16 bytes(ChaCha20-Poly1305 MAC)
• 發起者步驟:
1. 計算 ECDH:se = s_i * E_r
2. 加密自己的靜態公鑰
3. 發送,握手完成 金鑰衍生
HKDF Key Derivation: 握手狀態 (Handshake State): • h: 握手哈希(持續更新) • ck: 鏈接金鑰(用於 HKDF) • k: 當前加密金鑰 • n: nonce(計數器) 初始化 (Initialization): • 協議名稱:"Noise_XK_secp256k1_ChaChaPoly_SHA256" • h = SHA256(protocol_name || prologue) • ck = h • prologue = "lightning" HKDF 擴展: • (ck, k) = HKDF(ck, input_key_material) • 每次 ECDH 計算後: - 混入 ECDH 結果 - 更新 ck 和 k - 重置 nonce 最終金鑰 (Final Keys): • 發送金鑰:用於加密發送的訊息 • 接收金鑰:用於解密接收的訊息 • 兩個金鑰通過最終 HKDF 分割獲得
訊息加密
Message Encryption (Post-Handshake):
Encrypted Message Format:
+----------------+------------------+------------+
| Length Cipher | Message Cipher | MAC |
| (18 bytes) | (variable) | (16 bytes) |
+----------------+------------------+------------+
長度密文 (Length Ciphertext):
• 原始長度:2 bytes(big-endian)
• 加密後:2 bytes
• MAC:16 bytes
訊息密文 (Message Ciphertext):
• 原始訊息:最大 65535 bytes
• MAC:16 bytes
加密算法 (ChaCha20-Poly1305 AEAD):
• 加密:
ciphertext = ChaCha20(key, nonce, plaintext)
tag = Poly1305(key, ciphertext)
• nonce:64-bit 計數器,little-endian,前 4 bytes 為 0
• 每條訊息後 nonce++
金鑰輪換 (Key Rotation):
• 每 1000 條訊息輪換金鑰:
if (nonce >= 1000) {
(ck, k) = HKDF(ck, k)
nonce = 0
}
• 前向安全:舊金鑰無法解密新訊息 連接管理
Ping/Pong
定期發送 ping 訊息保持連接活躍。 對方必須以 pong 回應。可用於估計延遲。
Init 訊息
握手後第一個訊息。交換功能位, 確定雙方支援的協議功能。
Warning/Error
warning 訊息用於非致命問題。 error 訊息可能導致通道或連接關閉。
重連機制
斷線後節點會自動嘗試重連。 channel_reestablish 訊息同步通道狀態。
連接命令
Connection Commands: LND: # Connect to node lncli connect <pubkey>@<host>:<port> # List connected peers lncli listpeers # Disconnect lncli disconnect <pubkey> # Get node info lncli getnodeinfo <pubkey> Core Lightning: # Connect to node lightning-cli connect <pubkey>@<host>:<port> # List peers lightning-cli listpeers # Disconnect lightning-cli disconnect <pubkey> # Node info lightning-cli listnodes <pubkey> 連接狀態 (Connection States): • Connecting:正在建立 TCP 連接 • Noise handshake:正在進行加密握手 • Init exchange:交換功能位 • Connected:完全連接 • Reconnecting:斷線重連中
Tor 連接: 使用 Tor 隱藏 IP 地址。節點可以只透過 .onion 地址公告, 增強隱私但可能增加延遲。
相關資源
下一步: 了解 Gossip 協議 如何在節點間傳播網路資訊。
已複製連結