跳至主要內容
高級

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 協議 如何在節點間傳播網路資訊。

已複製連結
已複製到剪貼簿