Skip to content

ADR-0003. Mã hoá payload ECDH + AES-256-GCM bắt buộc trên /stream

TrườngGiá trị
StatusAccepted
Date2026-03-28
Deciderssignal-team
Supersedes

Bối cảnh

  • TLS kết thúc tại Traefik; sau nó, traffic băng qua network nội bộ và một bus Redis dùng chung.
  • Payload WebSocket mang dữ liệu order/payment không nên đọc được ở bus hay bởi kết nối co-tenant khác.
  • Chúng ta muốn cô lập khoá theo từng kết nối và forward secrecy mà không cần một service quản lý khoá.

Quyết định

Chúng ta sẽ yêu cầu mã hoá payload đầu-cuối cho mọi kết nối /stream (requireEncryption: true):

  • Trong handshake client gửi clientPublicKey; server sinh một cặp khoá ECDH P-256 ephemeral, derive một khoá AES-256 qua HKDF-SHA-256, và lưu nó trong một map _clientAesKeys in-memory khoá theo client id.
  • Server trả { serverPublicKey, salt } bên trong sự kiện connected để client derive cùng khoá.
  • Mọi message tiếp theo là AES-256-GCM { iv, ct }. Chỉ connectederror gửi plaintext.
  • Khoá xoá khi disconnect và mất khi restart (client reconnect để re-derive).

Hệ quả

ƯuNhược
Payload mờ trên dây, bus, và với kết nối khácKhông lưu — restart ép mọi client reconnect
Forward secrecy (khoá ephemeral mỗi kết nối)clientPublicKey bắt buộc — client không ECDH bị từ chối
Không cần KMS bên ngoàiMap khoá in-memory giới hạn một process; dựa vào sticky socket + Redis để scale

Phương án đã cân nhắc

Phương ánƯuNhượcVì sao loại
Chỉ TLS (không mã hoá payload)Đơn giản nhấtPlaintext sau Traefik + trên bus RedisKhông đủ cho dữ liệu payment
Khoá AES tĩnh dùng chungKhông handshakeKhông forward secrecy; một rò làm lộ tất cảBán kính ảnh hưởng không chấp nhận được
mTLS theo từng clientĐịnh danh mạnhVòng đời cert nặng trên client POS/TauriVận hành bất khả thi cho đội client

Tham chiếu

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.