Ghi chú
Giai đoạn đề xuất đã đóng. Xem SPEC để biết thông số kỹ thuật chính thức. Đề xuất này vẫn có thể được tham khảo để biết thông tin nền.
Tổng quan
Đề xuất này mô tả một giao thức thỏa thuận khóa có xác thực nhằm cải thiện khả năng chống lại các hình thức nhận dạng tự động và tấn công khác nhau của NTCP.
Đề xuất được tổ chức như sau: các mục tiêu bảo mật được trình bày, tiếp theo là thảo luận về giao thức cơ bản. Tiếp đó, một đặc tả hoàn chỉnh của tất cả các thông điệp giao thức được đưa ra. Cuối cùng, địa chỉ router và nhận dạng phiên bản được thảo luận. Phụ lục thảo luận về một cuộc tấn công chung đối với các lược đồ padding phổ biến cũng được bao gồm, cùng với phụ lục chứa một số ứng viên cho mã hóa xác thực.
Giống như các giao thức vận chuyển I2P khác, NTCP2 được định nghĩa chỉ cho việc vận chuyển thông điệp I2NP từ điểm đến điểm (router đến router). Nó không phải là một đường ống dữ liệu đa mục đích.
Động lực
Dữ liệu NTCP được mã hóa sau thông điệp đầu tiên (và thông điệp đầu tiên có vẻ là dữ liệu ngẫu nhiên), do đó ngăn chặn việc nhận dạng giao thức thông qua “phân tích payload”. Tuy nhiên nó vẫn dễ bị tổn thương với việc nhận dạng giao thức thông qua “phân tích luồng”. Đó là bởi vì 4 thông điệp đầu tiên (tức là quá trình bắt tay) có độ dài cố định (288, 304, 448, và 48 bytes).
Bằng cách thêm lượng dữ liệu ngẫu nhiên với số lượng ngẫu nhiên vào mỗi thông điệp, chúng ta có thể làm cho việc này khó khăn hơn rất nhiều.
Các tác giả thừa nhận rằng các thực hành bảo mật tiêu chuẩn sẽ đề xuất sử dụng một giao thức hiện có như TLS, nhưng đây là Prop104 và nó có những vấn đề riêng của mình. Ở những chỗ thích hợp, các đoạn “công việc tương lai” đã được thêm vào để chỉ ra các tính năng còn thiếu hoặc chủ đề thảo luận.
Mục Tiêu Thiết Kế
Hỗ trợ NTCP 1 và 2 trên một cổng duy nhất, tự động phát hiện, và được công bố như một “transport” duy nhất (tức là RouterAddress) trong NetDB.
Xuất bản hỗ trợ cho chỉ phiên bản 1, chỉ phiên bản 2, hoặc 1+2 trong netDb trong một trường riêng biệt, và mặc định chỉ phiên bản 1 (không ràng buộc hỗ trợ phiên bản với một phiên bản router cụ thể)
Đảm bảo rằng tất cả các triển khai (Java/i2pd/Kovri/go) có thể thêm hỗ trợ phiên bản 2 (hoặc không) theo lịch trình riêng của chúng
Thêm padding ngẫu nhiên vào tất cả các thông điệp NTCP bao gồm thông điệp handshake và thông điệp dữ liệu (tức là làm mờ độ dài để tất cả thông điệp không phải là bội số của 16 byte) Cung cấp cơ chế tùy chọn cho cả hai bên để yêu cầu padding tối thiểu và tối đa và/hoặc phân phối padding. Các chi tiết cụ thể của phân phối padding phụ thuộc vào việc triển khai và có thể được hoặc không được chỉ định trong chính giao thức.
Làm xáo trộn nội dung của các thông điệp không được mã hóa (1 và 2), đủ mức để các hộp DPI và chữ ký AV không thể dễ dàng phân loại chúng. Đồng thời đảm bảo rằng các thông điệp gửi đến một peer hoặc tập hợp các peer không có mẫu bit tương tự nhau.
Sửa lỗi mất bit trong DH do định dạng Java Ticket1112, có thể (có lẽ?) bằng cách chuyển sang X25519.
Chuyển sang sử dụng hàm dẫn xuất khóa thực (KDF) thay vì sử dụng trực tiếp kết quả DH?
Thêm “khả năng chống thăm dò” (như Tor gọi); bao gồm khả năng chống replay.
Duy trì trao đổi khóa xác thực 2 chiều (2W-AKE). 1W-AKE không đủ cho ứng dụng của chúng ta.
Tiếp tục sử dụng các chữ ký có kiểu biến đổi, độ dài biến đổi (từ khóa ký RouterIdentity đã công bố) như một phần của xác thực. Dựa vào khóa công khai tĩnh được công bố trong RouterInfo như một phần khác của xác thực.
Thêm options/version trong handshake để mở rộng trong tương lai.
Thêm khả năng chống lại việc phân đoạn TCP độc hại MitM nếu có thể.
Không tăng đáng kể CPU cần thiết cho việc thiết lập kết nối; nếu có thể, giảm đáng kể.
Thêm xác thực thông điệp (MAC), có thể là HMAC-SHA256 và Poly1305, và xóa bỏ checksum Adler.
Rút gọn và đơn giản hóa header I2NP: Rút gọn thời gian hết hạn xuống 4 bytes, như trong SSU. Loại bỏ checksum SHA256 bị cắt ngắn một byte.
Nếu có thể, giảm bắt tay 4 tin nhắn, hai lần khứ hồi xuống bắt tay 3 tin nhắn, một lần khứ hồi, như trong SSU. Điều này sẽ yêu cầu chuyển chữ ký của Bob từ tin nhắn 4 sang tin nhắn 2. Nghiên cứu lý do cho 4 tin nhắn trong kho lưu trữ email/trạng thái/cuộc họp cũ mười năm.
Giảm thiểu overhead của protocol trước khi padding. Mặc dù padding sẽ được thêm vào, và có thể rất nhiều, overhead trước padding vẫn là overhead. Các node băng thông thấp phải có khả năng sử dụng NTCP2.
Duy trì timestamps để phát hiện replay và skew.
Tránh mọi vấn đề năm 2038 trong timestamp, phải hoạt động ít nhất đến năm 2106.
Tăng kích thước tin nhắn tối đa từ 16K lên 32K hoặc 64K.
Bất kỳ primitive mật mã học nào mới đều nên có sẵn trong các thư viện để sử dụng trong các triển khai router Java (1.7), C++, và Go.
Bao gồm đại diện của các nhà phát triển router Java, C++, và Go trong thiết kế.
Giảm thiểu các thay đổi (nhưng vẫn sẽ có rất nhiều).
Hỗ trợ cả hai phiên bản trong một bộ mã chung (điều này có thể không khả thi và phụ thuộc vào việc triển khai trong mọi trường hợp).
Non-Goals
Khả năng chống DPI không thể phá vỡ… đó sẽ là pluggable transports, Prop109.
Một giao thức vận chuyển dựa trên TLS (hoặc giống HTTPS)… đó sẽ là Prop104.
Có thể thay đổi mã hóa luồng đối xứng.
Khả năng chống DPI dựa trên thời gian (timing giữa các thông điệp/độ trễ có thể phụ thuộc vào cách triển khai; độ trễ trong thông điệp có thể được đưa vào tại bất kỳ điểm nào, bao gồm trước khi gửi random padding chẳng hạn). Độ trễ nhân tạo (những gì obfs4 gọi là IAT hoặc inter-arrival time) độc lập với giao thức.
Khả năng phủ nhận việc tham gia vào một phiên (có chữ ký trong đó).
Các mục tiêu không ưu tiên có thể được xem xét lại một phần hoặc thảo luận:
Mức độ bảo vệ chống lại Deep Packet Inspection (DPI)
Bảo mật Post-Quantum (PQ)
Khả năng phủ nhận
Related Goals
- Triển khai thiết lập thử nghiệm NTCP 1/2
Security Goals
Chúng tôi xem xét ba bên:
- Alice, người muốn thiết lập một phiên mới.
- Bob, người mà Alice muốn thiết lập phiên kết nối.
- Mallory, kẻ “trung gian” (man in the middle) giữa Alice và Bob.
Tối đa hai người tham gia có thể thực hiện các cuộc tấn công chủ động.
Alice và Bob đều sở hữu một cặp khóa tĩnh, được chứa trong RouterIdentity của họ.
Giao thức được đề xuất cố gắng cho phép Alice và Bob thống nhất về một khóa bí mật chung (K) dưới các yêu cầu sau:
Bảo mật khóa riêng tư: cả Bob và Mallory đều không thể biết được bất cứ điều gì về khóa riêng tư tĩnh của Alice. Tương tự, Alice cũng không biết được bất cứ điều gì về khóa riêng tư tĩnh của Bob.
Khóa phiên K chỉ được biết bởi Alice và Bob.
Bảo mật chuyển tiếp hoàn hảo (Perfect forward secrecy): khóa phiên đã thỏa thuận vẫn được bảo mật trong tương lai, ngay cả khi khóa riêng tĩnh của Alice và/hoặc Bob bị tiết lộ sau khi khóa đã được thỏa thuận.
Xác thực hai chiều: Alice chắc chắn rằng cô ấy đã thiết lập một phiên với Bob, và ngược lại.
Bảo vệ chống DPI trực tuyến: Đảm bảo rằng việc phát hiện Alice và Bob đang tham gia vào giao thức này không đơn giản chỉ bằng cách sử dụng các kỹ thuật kiểm tra gói tin sâu (DPI) thông thường. Xem bên dưới.
Khả năng chối bỏ có giới hạn: không Alice hay Bob có thể chối bỏ việc tham gia vào giao thức, nhưng nếu một trong hai bên tiết lộ khóa chia sẻ thì bên kia có thể chối bỏ tính xác thực của nội dung dữ liệu được truyền.
Đề xuất hiện tại cố gắng cung cấp tất cả năm yêu cầu dựa trên giao thức Station-To-Station (STS). Lưu ý rằng giao thức này cũng là cơ sở cho giao thức SSU.
Additional DPI Discussion
Chúng tôi giả định có hai thành phần DPI:
1) Online DPI
DPI trực tuyến kiểm tra tất cả các luồng dữ liệu trong thời gian thực. Các kết nối có thể bị chặn hoặc can thiệp theo cách khác. Dữ liệu kết nối hoặc metadata có thể được xác định và lưu trữ để phân tích ngoại tuyến. DPI trực tuyến không có quyền truy cập vào cơ sở dữ liệu mạng I2P. DPI trực tuyến chỉ có khả năng tính toán thời gian thực hạn chế, bao gồm tính toán độ dài, kiểm tra trường dữ liệu, và các phép tính đơn giản như XOR. DPI trực tuyến có khả năng thực hiện các chức năng mật mã thời gian thực nhanh như AES, AEAD, và hashing, nhưng những chức năng này sẽ quá tốn kém để áp dụng cho hầu hết hoặc tất cả các luồng dữ liệu. Bất kỳ ứng dụng nào của các phép toán mật mã này sẽ chỉ áp dụng cho các luồng dữ liệu trên các tổ hợp IP/Port đã được xác định trước đó bởi phân tích ngoại tuyến. DPI trực tuyến không có khả năng thực hiện các chức năng mật mã có chi phí cao như DH hoặc elligator2. DPI trực tuyến không được thiết kế đặc biệt để phát hiện I2P, mặc dù nó có thể có các quy tắc phân loại hạn chế cho mục đích đó.
Mục tiêu là ngăn chặn việc nhận dạng giao thức bởi DPI trực tuyến.
Khái niệm về DPI trực tuyến hoặc “đơn giản” ở đây được hiểu là bao gồm các khả năng đối thủ sau:
Khả năng kiểm tra tất cả dữ liệu được gửi hoặc nhận bởi mục tiêu.
Khả năng thực hiện các thao tác trên dữ liệu quan sát được, chẳng hạn như áp dụng block cipher hoặc hash function.
Khả năng lưu trữ và so sánh với các tin nhắn đã gửi trước đó.
Khả năng sửa đổi, trì hoãn hoặc phân mảnh các packet.
Tuy nhiên, DPI trực tuyến được giả định có những hạn chế sau:
Không thể ánh xạ địa chỉ IP thành router hash. Mặc dù điều này khá đơn giản với quyền truy cập thời gian thực vào cơ sở dữ liệu mạng, nó sẽ yêu cầu một hệ thống DPI được thiết kế đặc biệt để nhắm mục tiêu I2P.
Không thể sử dụng thông tin thời gian để phát hiện giao thức.
Nói chung, bộ công cụ DPI trực tuyến không chứa bất kỳ công cụ tích hợp nào được thiết kế riêng để phát hiện I2P. Điều này bao gồm việc tạo ra các “honeypot”, ví dụ như bao gồm padding không ngẫu nhiên trong các thông điệp của chúng. Lưu ý rằng điều này không loại trừ các hệ thống machine learning hoặc các công cụ DPI có khả năng cấu hình cao miễn là chúng đáp ứng các yêu cầu khác.
Để chống lại phân tích payload, cần đảm bảo rằng tất cả các thông điệp đều không thể phân biệt được với dữ liệu ngẫu nhiên. Điều này cũng yêu cầu độ dài của chúng phải ngẫu nhiên, điều này phức tạp hơn việc chỉ đơn giản thêm padding ngẫu nhiên. Thực tế, trong Phụ lục A, các tác giả lập luận rằng một lược đồ padding đơn giản (tức là đồng đều) không giải quyết được vấn đề. Do đó, Phụ lục A đề xuất bao gồm các độ trễ ngẫu nhiên hoặc phát triển một lược đồ padding thay thế có thể cung cấp bảo vệ hợp lý cho cuộc tấn công được đề xuất.
Để bảo vệ chống lại mục thứ sáu ở trên, các triển khai nên bao gồm độ trễ ngẫu nhiên trong giao thức. Những kỹ thuật như vậy không được đề cập trong đề xuất này, nhưng chúng cũng có thể giải quyết các vấn đề về độ dài padding. Tóm lại, đề xuất này cung cấp khả năng bảo vệ tốt chống lại phân tích payload (khi các cân nhắc trong Phụ lục A được tính đến), nhưng chỉ có khả năng bảo vệ hạn chế chống lại phân tích luồng dữ liệu.
2) Offline DPI
DPI ngoại tuyến kiểm tra dữ liệu được lưu trữ bởi DPI trực tuyến để phân tích sau này. DPI ngoại tuyến có thể được thiết kế đặc biệt để phát hiện I2P. DPI ngoại tuyến không có quyền truy cập thời gian thực vào cơ sở dữ liệu mạng I2P. DPI ngoại tuyến có quyền truy cập vào thông số kỹ thuật này và các thông số kỹ thuật I2P khác. DPI ngoại tuyến có khả năng tính toán không giới hạn, bao gồm tất cả các chức năng mật mã được định nghĩa trong thông số kỹ thuật này.
DPI ngoại tuyến không có khả năng chặn các kết nối hiện có. DPI ngoại tuyến có khả năng gửi gần thời gian thực (trong vòng vài phút sau khi thiết lập) đến host/port của các bên, ví dụ như TCP RST. DPI ngoại tuyến có khả năng phát lại gần thời gian thực (trong vòng vài phút sau khi thiết lập) các tin nhắn trước đó (đã sửa đổi hoặc không) để “thăm dò” hoặc vì các lý do khác.
Không phải là mục tiêu để ngăn chặn việc nhận dạng giao thức bởi DPI ngoại tuyến. Tất cả việc giải mã dữ liệu bị làm rối trong hai thông điệp đầu tiên, được thực hiện bởi các I2P router, cũng có thể được thực hiện bởi DPI ngoại tuyến.
Mục tiêu là từ chối các kết nối có ý định sử dụng replay của các thông điệp trước đó.
Future work
Xem xét hành vi của giao thức khi các gói tin bị loại bỏ hoặc sắp xếp lại bởi kẻ tấn công. Nghiên cứu thú vị gần đây trong lĩnh vực này có thể tìm thấy tại IACR-1150.
Cung cấp một phân loại chính xác hơn về các hệ thống DPI, có tính đến tài liệu hiện có liên quan đến chủ đề này.
Thảo luận về tính bảo mật chính thức của giao thức được đề xuất, lý tưởng nhất là có tính đến mô hình tấn công DPI.
Noise Protocol Framework
Đề xuất này cung cấp các yêu cầu dựa trên Noise Protocol Framework NOISE (Phiên bản 33, 2017-10-04). Noise có các đặc tính tương tự như giao thức Station-To-Station, là nền tảng cho giao thức SSU. Trong thuật ngữ của Noise, Alice là bên khởi tạo và Bob là bên phản hồi.
NTCP2 dựa trên giao thức Noise Noise_XK_25519_ChaChaPoly_SHA256. (Định danh thực tế cho hàm dẫn xuất khóa ban đầu là “Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256” để chỉ ra các phần mở rộng I2P - xem phần KDF 1 bên dưới) Giao thức Noise này sử dụng các nguyên thủy sau:
Handshake Pattern: XK Alice truyền key của mình cho Bob (X) Alice đã biết static key của Bob trước đó (K)
DH Function: X25519 X25519 DH với độ dài khóa 32 byte như được quy định trong RFC-7748.
Cipher Function: ChaChaPoly AEAD_CHACHA20_POLY1305 như được quy định trong RFC-7539 phần 2.8. 12 byte nonce, với 4 byte đầu tiên được đặt bằng không.
Hash Function: SHA256 Hàm băm chuẩn 32-byte, đã được sử dụng rộng rãi trong I2P.
Mục Tiêu Bảo Mật
Đề xuất này định nghĩa các cải tiến sau đây cho Noise_XK_25519_ChaChaPoly_SHA256. Những cải tiến này nhìn chung tuân theo các hướng dẫn trong NOISE phần 13.
Các khóa tạm thời dạng văn bản rõ được làm mờ bằng mã hóa AES sử dụng khóa và IV đã biết. Điều này nhanh hơn so với elligator2.
Padding cleartext ngẫu nhiên được thêm vào tin nhắn 1 và 2. Padding cleartext được bao gồm trong tính toán hash handshake (MixHash). Xem các phần KDF bên dưới cho tin nhắn 2 và tin nhắn 3 phần 1. Padding AEAD ngẫu nhiên được thêm vào tin nhắn 3 và các tin nhắn pha dữ liệu.
Một trường độ dài frame hai byte được thêm vào, như yêu cầu cho Noise qua TCP, và như trong obfs4. Điều này chỉ được sử dụng trong các thông điệp giai đoạn dữ liệu. Các frame AEAD thông điệp 1 và 2 có độ dài cố định. Frame AEAD thông điệp 3 phần 1 có độ dài cố định. Độ dài frame AEAD thông điệp 3 phần 2 được chỉ định trong thông điệp 1.
Trường độ dài khung hai byte được làm xáo trộn bằng SipHash-2-4, như trong obfs4.
Định dạng payload được xác định cho các thông điệp 1,2,3, và giai đoạn dữ liệu. Tất nhiên, điều này không được định nghĩa trong Noise.
New Cryptographic Primitives for I2P
Các triển khai I2P router hiện tại sẽ yêu cầu các triển khai cho các nguyên thủy mật mã chuẩn sau đây, những thứ không được yêu cầu cho các giao thức I2P hiện tại:
Tạo khóa X25519 và DH
AEAD_ChaCha20_Poly1305 (viết tắt là ChaChaPoly bên dưới)
SipHash-2-4
Processing overhead estimate
Kích thước tin nhắn cho 3 tin nhắn:
- 64 byte + padding (NTCP là 288 byte) 2) 64 byte + padding (NTCP là 304 byte) 3) khoảng 64 byte + thông tin router Alice + padding Thông tin router trung bình khoảng 750 byte Tổng trung bình 814 byte trước khi padding (NTCP là 448 byte) 4) không yêu cầu trong NTCP2 (NTCP là 48 byte)
Tổng trước khi padding: NTCP2: 942 bytes NTCP: 1088 bytes Lưu ý rằng nếu Alice kết nối với Bob với mục đích gửi DatabaseStore Message của RouterInfo của cô ấy, thì message đó không bắt buộc, tiết kiệm khoảng 800 bytes.
Các hoạt động mã hóa sau đây được yêu cầu bởi mỗi bên để hoàn tất quá trình bắt tay và bắt đầu giai đoạn dữ liệu:
- AES: 2
- SHA256: 7 (Alice), 6 (Bob) (không bao gồm 1 Alice, 2 Bob được tính toán trước cho tất cả các kết nối) (không bao gồm HMAC-SHA256)
- HMAC-SHA256: 19
- ChaChaPoly: 4
- Tạo khóa X25519: 1
- X25519 DH: 3
- Xác thực chữ ký: 1 (Bob) (Alice đã ký trước đó khi tạo RI của cô ấy) Có thể là Ed25519 (phụ thuộc vào loại chữ ký RI)
Các thao tác mật mã sau đây được yêu cầu bởi mỗi bên cho mỗi thông điệp giai đoạn dữ liệu:
- SipHash: 1
- ChaChaPoly: 1
Messages
Tất cả thông điệp NTCP2 có độ dài nhỏ hơn hoặc bằng 65537 byte. Định dạng thông điệp dựa trên thông điệp Noise, với các chỉnh sửa cho việc đóng khung và tính không thể phân biệt. Các triển khai sử dụng thư viện Noise tiêu chuẩn có thể cần xử lý trước các thông điệp nhận được sang/từ định dạng thông điệp Noise. Tất cả các trường được mã hóa đều là bản mã AEAD.
Trình tự thiết lập như sau:
Alice Bob
SessionRequest ------------------->
<------------------- SessionCreated
SessionConfirmed ----------------->
Sử dụng thuật ngữ Noise, trình tự thiết lập và dữ liệu như sau: (Thuộc tính Bảo mật Payload)
XK(s, rs): Authentication Confidentiality
<- s
...
-> e, es 0 2
<- e, ee 2 1
-> s, se 2 5
<- 2 5
Một khi phiên kết nối đã được thiết lập, Alice và Bob có thể trao đổi các thông điệp Data.
Tất cả các loại thông điệp (SessionRequest, SessionCreated, SessionConfirmed, Data và TimeSync) được chỉ định trong phần này.
Một số ký hiệu:
- RH_A = Router Hash cho Alice (32 bytes)
- RH_B = Router Hash cho Bob (32 bytes)
Authenticated Encryption
Có ba thể hiện mã hóa xác thực riêng biệt (CipherStates). Một thể hiện trong giai đoạn handshake, và hai thể hiện (truyền và nhận) cho giai đoạn dữ liệu. Mỗi thể hiện có khóa riêng từ một KDF.
Dữ liệu được mã hóa/xác thực sẽ được biểu diễn như
+----+----+----+----+----+----+----+----+
| |
+ +
| Encrypted and authenticated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Các Mục Tiêu Không Ưu Tiên
Định dạng dữ liệu được mã hóa và xác thực.
Đầu vào cho các hàm mã hóa/giải mã:
k :: 32 byte cipher key, as generated from KDF
nonce :: Counter-based nonce, 12 bytes.
Starts at 0 and incremented for each message.
First four bytes are always zero.
Last eight bytes are the counter, little-endian encoded.
Maximum value is 2**64 - 2.
Connection must be dropped and restarted after
it reaches that value.
The value 2**64 - 1 must never be sent.
ad :: In handshake phase:
Associated data, 32 bytes.
The SHA256 hash of all preceding data.
In data phase:
Zero bytes
data :: Plaintext data, 0 or more bytes
Đầu ra của hàm mã hóa, đầu vào của hàm giải mã:
+----+----+----+----+----+----+----+----+
|Obfs Len | |
+----+----+ +
| ChaCha20 encrypted data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) +
| 16 bytes |
+----+----+----+----+----+----+----+----+
Obfs Len :: Length of (encrypted data + MAC) to follow, 16 - 65535
Obfuscation using SipHash (see below)
Not used in message 1 or 2, or message 3 part 1, where the length is fixed
Not used in message 3 part 1, as the length is specified in message 1
encrypted data :: Same size as plaintext data, 0 - 65519 bytes
MAC :: Poly1305 message authentication code, 16 bytes
Đối với ChaCha20, những gì được mô tả ở đây tương ứng với RFC-7539, cũng được sử dụng tương tự trong TLS RFC-7905.
Notes
Vì ChaCha20 là một stream cipher, plaintext không cần được padding. Các byte keystream bổ sung sẽ bị loại bỏ.
Khóa cho thuật toán mã hóa (256 bit) được thỏa thuận thông qua SHA256 KDF. Chi tiết của KDF cho từng message được trình bày trong các phần riêng biệt bên dưới.
Các frame ChaChaPoly cho thông điệp 1, 2, và phần đầu tiên của thông điệp 3, có kích thước đã biết. Bắt đầu từ phần thứ hai của thông điệp 3, các frame có kích thước biến đổi. Kích thước phần 1 của thông điệp 3 được chỉ định trong thông điệp 1. Bắt đầu từ giai đoạn dữ liệu, các frame được thêm tiền tố với độ dài hai byte được làm xáo trộn bằng SipHash như trong obfs4.
Padding nằm bên ngoài khung dữ liệu được xác thực cho thông điệp 1 và 2. Padding được sử dụng trong KDF cho thông điệp tiếp theo nên việc can thiệp sẽ được phát hiện. Bắt đầu từ thông điệp 3, padding nằm bên trong khung dữ liệu được xác thực.
Các Mục Tiêu Liên Quan
Trong message 1, 2, và message 3 phần 1 và 2, kích thước message AEAD được biết trước. Khi xác thực AEAD thất bại, bên nhận phải dừng xử lý message tiếp theo và đóng kết nối mà không phản hồi. Đây nên là một đóng kết nối bất thường (TCP RST).
Để chống thăm dò, trong thông điệp 1, sau khi AEAD thất bại, Bob nên đặt một thời gian timeout ngẫu nhiên (phạm vi sẽ được xác định) và sau đó đọc một số lượng byte ngẫu nhiên (phạm vi sẽ được xác định) trước khi đóng socket. Bob nên duy trì một danh sách đen các IP với các lần thất bại lặp đi lặp lại.
Trong giai đoạn dữ liệu, kích thước thông điệp AEAD được “mã hóa” (làm rối) bằng SipHash. Cần phải cẩn thận để tránh tạo ra một oracle giải mã. Khi xảy ra lỗi xác thực AEAD trong giai đoạn dữ liệu, bên nhận nên đặt một thời gian chờ ngẫu nhiên (phạm vi TBD) và sau đó đọc một số byte ngẫu nhiên (phạm vi TBD). Sau khi đọc xong, hoặc khi hết thời gian chờ đọc, bên nhận nên gửi một payload với một khối kết thúc chứa mã lý do “lỗi AEAD”, và đóng kết nối.
Thực hiện cùng một hành động lỗi cho giá trị trường độ dài không hợp lệ trong giai đoạn dữ liệu.
Key Derivation Function (KDF) (for handshake message 1)
KDF tạo ra một khóa cipher pha handshake k từ kết quả DH, sử dụng HMAC-SHA256(key, data) như được định nghĩa trong RFC-2104. Đây là các hàm InitializeSymmetric(), MixHash(), và MixKey(), hoàn toàn như được định nghĩa trong đặc tả Noise.
This is the "e" message pattern:
// Define protocol_name.
Set protocol_name = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
(48 bytes, US-ASCII encoded, no NULL termination).
// Define Hash h = 32 bytes
h = SHA256(protocol_name);
Define ck = 32 byte chaining key. Copy the h data to ck.
Set ck = h
Define rs = Bob's 32-byte static key as published in the RouterInfo
// MixHash(null prologue)
h = SHA256(h);
// up until here, can all be precalculated by Alice for all outgoing connections
// Alice must validate that Bob's static key is a valid point on the curve here.
// Bob static key
// MixHash(rs)
// || below means append
h = SHA256(h || rs);
// up until here, can all be precalculated by Bob for all incoming connections
This is the "e" message pattern:
Alice generates her ephemeral DH key pair e.
// Alice ephemeral key X
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 1
// Retain the Hash h for the message 2 KDF
End of "e" message pattern.
This is the "es" message pattern:
// DH(e, rs) == DH(s, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's static key
Set input_key_material = X25519 DH result
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, defined above
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 2 KDF
End of "es" message pattern.
Thảo luận Bổ sung về DPI
Alice gửi cho Bob.
Noise content: Khóa tạm thời X của Alice Noise payload: Khối tùy chọn 16 byte Non-noise payload: Padding ngẫu nhiên
(Thuộc tính Bảo mật Payload)
XK(s, rs): Authentication Confidentiality
-> e, es 0 2
Authentication: None (0).
This payload may have been sent by any party, including an active attacker.
Confidentiality: 2.
Encryption to a known recipient, forward secrecy for sender compromise
only, vulnerable to replay. This payload is encrypted based only on DHs
involving the recipient's static key pair. If the recipient's static
private key is compromised, even at a later date, this payload can be
decrypted. This message can also be replayed, since there's no ephemeral
contribution from the recipient.
"e": Alice generates a new ephemeral key pair and stores it in the e
variable, writes the ephemeral public key as cleartext into the
message buffer, and hashes the public key along with the old h to
derive a new h.
"es": A DH is performed between the Alice's ephemeral key pair and the
Bob's static key pair. The result is hashed along with the old ck to
derive a new ck and k, and n is set to zero.
Giá trị X được mã hóa để đảm bảo tính không phân biệt được và tính duy nhất của payload, đây là những biện pháp đối phó DPI cần thiết. Chúng tôi sử dụng mã hóa AES để đạt được điều này, thay vì các phương án phức tạp và chậm hơn như elligator2. Mã hóa bất đối xứng với khóa công khai của router Bob sẽ quá chậm. Mã hóa AES sử dụng hash của router Bob làm khóa và IV của Bob như được xuất bản trong network database.
Mã hóa AES chỉ dành cho việc chống DPI. Bất kỳ bên nào biết hash router của Bob và IV, được công bố trong cơ sở dữ liệu mạng, đều có thể giải mã giá trị X trong thông điệp này.
Phần padding không được mã hóa bởi Alice. Bob có thể cần giải mã phần padding để ngăn chặn các cuộc tấn công timing.
Nội dung thô:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaChaPoly frame |
+ (32 bytes) +
| k defined in KDF for message 1 |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
~ padding (optional) ~
| length defined in options block |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: As published in Bobs network database entry
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as NTCP
(see Version Detection section below).
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
Dữ liệu không được mã hóa (thẻ xác thực Poly1305 không được hiển thị):
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as "NTCP"
(see Version Detection section below)
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
Khối tùy chọn: Lưu ý: Tất cả các trường đều là big-endian.
+----+----+----+----+----+----+----+----+
| id | ver| padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
| tsA | Reserved (0) |
+----+----+----+----+----+----+----+----+
id :: 1 byte, the network ID (currently 2, except for test networks)
As of 0.9.42. See proposal 147.
ver :: 1 byte, protocol version (currently 2)
padLen :: 2 bytes, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
m3p2Len :: 2 bytes, length of the the second AEAD frame in SessionConfirmed
(message 3 part 2) See notes below
Rsvd :: 2 bytes, set to 0 for compatibility with future options
tsA :: 4 bytes, Unix timestamp, unsigned seconds.
Wraps around in 2106
Reserved :: 4 bytes, set to 0 for compatibility with future options
Notes
Khi địa chỉ được công bố là “NTCP”, Bob hỗ trợ cả NTCP và NTCP2 trên cùng một cổng. Để tương thích, khi khởi tạo kết nối đến một địa chỉ được công bố là “NTCP”, Alice phải giới hạn kích thước tối đa của thông điệp này, bao gồm cả padding, xuống 287 byte hoặc ít hơn. Điều này tạo điều kiện cho việc nhận dạng giao thức tự động bởi Bob. Khi được công bố là “NTCP2”, không có hạn chế về kích thước. Xem các phần Địa chỉ Công bố và Phát hiện Phiên bản bên dưới.
Giá trị X duy nhất trong khối AES ban đầu đảm bảo rằng bản mã hóa sẽ khác nhau cho mỗi phiên.
Bob phải từ chối các kết nối có giá trị timestamp quá xa so với thời gian hiện tại. Gọi khoảng thời gian tối đa là “D”. Bob phải duy trì một bộ nhớ đệm cục bộ các giá trị handshake đã sử dụng trước đó và từ chối các giá trị trùng lặp, để ngăn chặn các cuộc tấn công replay. Các giá trị trong bộ nhớ đệm phải có thời gian tồn tại ít nhất là 2*D. Các giá trị bộ nhớ đệm phụ thuộc vào implementation, tuy nhiên có thể sử dụng giá trị X 32-byte (hoặc tương đương đã mã hóa của nó).
Các khóa tạm thời Diffie-Hellman không bao giờ được tái sử dụng, để ngăn chặn các cuộc tấn công mật mã, và việc tái sử dụng sẽ bị từ chối như một cuộc tấn công replay.
Các tùy chọn “KE” và “auth” phải tương thích, tức là shared secret K phải có kích thước phù hợp. Nếu thêm nhiều tùy chọn “auth” hơn, điều này có thể thay đổi ngầm ý nghĩa của flag “KE” để sử dụng một KDF khác hoặc một kích thước truncation khác.
Bob phải xác thực rằng khóa tạm thời của Alice là một điểm hợp lệ trên đường cong tại đây.
Padding nên được giới hạn ở mức hợp lý. Bob có thể từ chối các kết nối có padding quá mức. Bob sẽ chỉ định các tùy chọn padding của mình trong message 2. Hướng dẫn Min/max TBD. Kích thước ngẫu nhiên từ 0 đến 31 byte tối thiểu? (Phân phối sẽ được xác định, xem Phụ lục A.)
Khi có bất kỳ lỗi nào, bao gồm AEAD, DH, timestamp, replay rõ ràng, hoặc lỗi xác thực khóa, Bob phải dừng xử lý thông điệp và đóng kết nối mà không phản hồi. Đây phải là một lần đóng bất thường (TCP RST). Để chống thăm dò, sau một lỗi AEAD, Bob nên đặt một timeout ngẫu nhiên (phạm vi TBD) và sau đó đọc một số byte ngẫu nhiên (phạm vi TBD), trước khi đóng socket.
Giảm thiểu DoS: DH là một phép toán tương đối tốn kém. Giống như giao thức NTCP trước đó, các router nên thực hiện mọi biện pháp cần thiết để ngăn chặn cạn kiệt CPU hoặc kết nối. Đặt giới hạn về số kết nối hoạt động tối đa và số thiết lập kết nối đang tiến hành tối đa. Thực thi timeout đọc (cả theo mỗi lần đọc và tổng thể cho “slowloris”). Giới hạn các kết nối lặp lại hoặc đồng thời từ cùng một nguồn. Duy trì blacklist cho các nguồn thất bại lặp đi lặp lại. Không phản hồi lỗi AEAD.
Để tạo thuận lợi cho việc phát hiện phiên bản nhanh chóng và handshaking, các triển khai phải đảm bảo rằng Alice đệm và sau đó xả toàn bộ nội dung của thông điệp đầu tiên cùng một lúc, bao gồm cả padding. Điều này làm tăng khả năng dữ liệu sẽ được chứa trong một gói TCP duy nhất (trừ khi bị phân đoạn bởi hệ điều hành hoặc middlebox), và được Bob nhận cùng một lúc. Ngoài ra, các triển khai phải đảm bảo rằng Bob đệm và sau đó xả toàn bộ nội dung của thông điệp thứ hai cùng một lúc, bao gồm cả padding. và rằng Bob đệm và sau đó xả toàn bộ nội dung của thông điệp thứ ba cùng một lúc. Điều này cũng nhằm mục đích hiệu quả và đảm bảo tính hiệu quả của random padding.
Trường “ver”: Giao thức Noise tổng thể, các phần mở rộng, và giao thức NTCP bao gồm các đặc tả payload, cho biết NTCP2. Trường này có thể được sử dụng để chỉ ra sự hỗ trợ cho các thay đổi trong tương lai.
Độ dài phần 2 của tin nhắn 3: Đây là kích thước của khung AEAD thứ hai (bao gồm MAC 16-byte) chứa Router Info của Alice và padding tùy chọn sẽ được gửi trong tin nhắn SessionConfirmed. Vì các router định kỳ tái tạo và xuất bản lại Router Info của chúng, kích thước của Router Info hiện tại có thể thay đổi trước khi tin nhắn 3 được gửi. Các implementation phải chọn một trong hai chiến lược: a) lưu Router Info hiện tại để gửi trong tin nhắn 3, để biết được kích thước, và tùy chọn thêm chỗ cho padding; b) tăng kích thước được chỉ định đủ để cho phép khả năng tăng kích thước Router Info, và luôn thêm padding khi tin nhắn 3 thực sự được gửi. Trong cả hai trường hợp, độ dài “m3p2len” được bao gồm trong tin nhắn 1 phải chính xác bằng kích thước của khung đó khi được gửi trong tin nhắn 3.
Bob phải thất bại kết nối nếu còn bất kỳ dữ liệu đến nào sau khi xác thực message 1 và đọc padding. Không nên có dữ liệu bổ sung nào từ Alice, vì Bob chưa phản hồi với message 2.
Trường network ID được sử dụng để nhanh chóng xác định các kết nối xuyên mạng. Nếu trường này khác không và không khớp với network ID của Bob, Bob nên ngắt kết nối và chặn các kết nối trong tương lai. Kể từ phiên bản 0.9.42. Xem đề xuất 147 để biết thêm thông tin.
Key Derivation Function (KDF) (for handshake message 2 and message 3 part 1)
// take h saved from message 1 KDF
// MixHash(ciphertext)
h = SHA256(h || 32 byte encrypted payload from message 1)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 1)
This is the "e" message pattern:
Bob generates his ephemeral DH key pair e.
// h is from KDF for handshake message 1
// Bob ephemeral key Y
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 2
// Retain the Hash h for the message 3 KDF
End of "e" message pattern.
This is the "ee" message pattern:
// DH(e, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Alice's ephemeral key in memory, no longer needed
// Alice:
e(public and private) = (all zeros)
// Bob:
re = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 3 KDF
End of "ee" message pattern.
2) SessionCreated
Bob gửi cho Alice.
Nội dung Noise: Khóa tạm thời Y của Bob Tải trọng Noise: Khối tùy chọn 16 byte Tải trọng không phải Noise: Padding ngẫu nhiên
(Thuộc tính Bảo mật Payload)
XK(s, rs): Authentication Confidentiality
<- e, ee 2 1
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 1.
Encryption to an ephemeral recipient.
This payload has forward secrecy, since encryption involves an ephemeral-ephemeral DH ("ee").
However, the sender has not authenticated the recipient,
so this payload might be sent to any party, including an active attacker.
"e": Bob generates a new ephemeral key pair and stores it in the e variable,
writes the ephemeral public key as cleartext into the message buffer,
and hashes the public key along with the old h to derive a new h.
"ee": A DH is performed between the Bob's ephemeral key pair and the Alice's ephemeral key pair.
The result is hashed along with the old ck to derive a new ck and k, and n is set to zero.
Giá trị Y được mã hóa để đảm bảo tính không phân biệt được của payload và tính duy nhất, đây là các biện pháp đối phó DPI cần thiết. Chúng tôi sử dụng mã hóa AES để đạt được điều này, thay vì các phương pháp thay thế phức tạp và chậm hơn như elligator2. Mã hóa bất đối xứng bằng khóa công khai của router Alice sẽ quá chậm. Mã hóa AES sử dụng router hash của Bob làm khóa và trạng thái AES từ message 1 (được khởi tạo với IV của Bob như đã công bố trong network database).
Mã hóa AES chỉ dành cho khả năng chống DPI. Bất kỳ bên nào biết router hash và IV của Bob, được công bố trong netDb, và chặn được 32 byte đầu tiên của message 1, đều có thể giải mã giá trị Y trong thông điệp này.
Nội dung thô:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaChaPoly frame |
+ Encrypted and authenticated data +
| 32 bytes |
+ k defined in KDF for message 2 +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: Using AES state from message 1
Dữ liệu chưa mã hóa (Poly1305 auth tag không được hiển thị):
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Alice and Bob will use the padding data in the KDF for message 3 part 1.
It is authenticated so that any tampering will cause the
next message to fail.
Notes
Alice phải xác thực rằng khóa ephemeral của Bob là một điểm hợp lệ trên đường cong tại đây.
Padding nên được giới hạn ở mức hợp lý. Alice có thể từ chối các kết nối có padding quá mức. Alice sẽ chỉ định các tùy chọn padding của mình trong message 3. Hướng dẫn min/max sẽ được xác định sau. Kích thước ngẫu nhiên từ 0 đến 31 byte tối thiểu? (Phân phối sẽ được xác định, xem Phụ lục A.)
Khi có bất kỳ lỗi nào, bao gồm AEAD, DH, timestamp, replay rõ ràng, hoặc lỗi xác thực khóa, Alice phải dừng xử lý thông điệp tiếp theo và đóng kết nối mà không phản hồi. Đây nên là một đóng kết nối bất thường (TCP RST).
Để tạo điều kiện thuận lợi cho quá trình handshaking nhanh chóng, các implementation phải đảm bảo rằng Bob buffer và sau đó flush toàn bộ nội dung của message đầu tiên cùng một lúc, bao gồm cả padding. Điều này tăng khả năng dữ liệu sẽ được chứa trong một TCP packet duy nhất (trừ khi bị phân đoạn bởi OS hoặc middlebox), và được Alice nhận tất cả cùng một lúc. Điều này cũng nhằm mục đích hiệu quả và đảm bảo tính hiệu quả của random padding.
Alice phải từ chối kết nối nếu còn bất kỳ dữ liệu đến nào sau khi xác thực message 2 và đọc padding. Không nên có dữ liệu thêm từ Bob, vì Alice chưa phản hồi với message 3.
Khối tùy chọn: Lưu ý: Tất cả các trường đều theo định dạng big-endian.
+----+----+----+----+----+----+----+----+
| Rsvd(0) | padLen | Reserved (0) |
+----+----+----+----+----+----+----+----+
| tsB | Reserved (0) |
+----+----+----+----+----+----+----+----+
Reserved :: 10 bytes total, set to 0 for compatibility with future options
padLen :: 2 bytes, big endian, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
tsB :: 4 bytes, big endian, Unix timestamp, unsigned seconds.
Wraps around in 2106
Notes
- Alice phải từ chối các kết nối có giá trị timestamp quá xa so với thời gian hiện tại. Gọi khoảng thời gian tối đa này là “D”. Alice phải duy trì một bộ nhớ đệm cục bộ của các giá trị handshake đã sử dụng trước đó và từ chối các giá trị trùng lặp, để ngăn chặn các cuộc tấn công replay. Các giá trị trong bộ nhớ đệm phải có thời gian sống ít nhất là 2*D. Các giá trị bộ nhớ đệm phụ thuộc vào cách triển khai, tuy nhiên có thể sử dụng giá trị Y 32-byte (hoặc tương đương đã mã hóa).
Issues
- Có nên bao gồm các tùy chọn padding tối thiểu/tối đa ở đây không?
Encryption for for handshake message 3 part 1, using message 2 KDF)
// take h saved from message 2 KDF
// MixHash(ciphertext)
h = SHA256(h || 24 byte encrypted payload from message 2)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 2)
// h is used as the associated data for the AEAD in message 3 part 1, below
This is the "s" message pattern:
Define s = Alice's static public key, 32 bytes
// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// k is from handshake message 1
// n is 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// h is used as the associated data for the AEAD in message 3 part 2
End of "s" message pattern.
Key Derivation Function (KDF) (for handshake message 3 part 2)
This is the "se" message pattern:
// DH(s, re) == DH(e, rs)
Define input_key_material = 32 byte DH result of Alice's static key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Bob's ephemeral key in memory, no longer needed
// Alice:
re = (all zeros)
// Bob:
e(public and private) = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// h from message 3 part 1 is used as the associated data for the AEAD in message 3 part 2
// EncryptAndHash(payload)
// EncryptWithAd(h, payload)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// n is 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, payload)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// retain the chaining key ck for the data phase KDF
// retain the hash h for the data phase Additional Symmetric Key (SipHash) KDF
End of "se" message pattern.
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
3) SessionConfirmed
Alice gửi cho Bob.
Nội dung Noise: khóa tĩnh của Alice Payload Noise: RouterInfo của Alice và padding ngẫu nhiên Payload không phải noise: không có
(Thuộc Tính Bảo Mật Payload)
XK(s, rs): Authentication Confidentiality
-> s, se 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI). The
sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key
pair. Assuming the corresponding private keys are secure, this
authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy. This payload is
encrypted based on an ephemeral-ephemeral DH as well as an ephemeral-static
DH with the recipient's static key pair. Assuming the ephemeral private
keys are secure, and the recipient is not being actively impersonated by an
attacker that has stolen its static private key, this payload cannot be
decrypted.
"s": Alice writes her static public key from the s variable into the
message buffer, encrypting it, and hashes the output along with the old h
to derive a new h.
"se": A DH is performed between the Alice's static key pair and the Bob's
ephemeral key pair. The result is hashed along with the old ck to derive a
new ck and k, and n is set to zero.
Điều này chứa hai khung ChaChaPoly. Khung đầu tiên là static public key được mã hóa của Alice. Khung thứ hai là Noise payload: RouterInfo được mã hóa của Alice, các tùy chọn tùy ý, và padding tùy ý. Chúng sử dụng các khóa khác nhau, bởi vì hàm MixKey() được gọi ở giữa.
Nội dung thô:
+----+----+----+----+----+----+----+----+
| |
+ ChaChaPoly frame (48 bytes) +
| Encrypted and authenticated |
+ Alice static key S +
| (32 bytes) |
+ +
| k defined in KDF for message 2 |
+ n = 1 +
| see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ Length specified in message 1 +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ +
| Alice RouterInfo |
+ using block format 2 +
| Alice Options (optional) |
+ using block format 1 +
| Arbitrary padding |
+ using block format 254 +
| |
+ +
| k defined in KDF for message 3 part 2 |
+ n = 0 +
| see KDF for associated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, ChaChaPoly encrypted Alice's X25519 static key, little endian
inside 48 byte ChaChaPoly frame
Dữ liệu không mã hóa (không hiển thị thẻ xác thực Poly1305):
+----+----+----+----+----+----+----+----+
| |
+ +
| S |
+ Alice static key +
| (32 bytes) |
+ +
| |
+ +
+----+----+----+----+----+----+----+----+
| |
+ +
| |
+ +
| Alice RouterInfo block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Options block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Padding block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, Alice's X25519 static key, little endian
1) DPI Trực tuyến
Bob phải thực hiện xác thực Router Info thông thường. Đảm bảo loại chữ ký được hỗ trợ, xác minh chữ ký, xác minh timestamp nằm trong giới hạn cho phép, và bất kỳ kiểm tra cần thiết nào khác.
Bob phải xác minh rằng static key của Alice nhận được trong frame đầu tiên khớp với static key trong Router Info. Bob phải tìm kiếm Router Info trước để tìm một NTCP hoặc NTCP2 Router Address với tùy chọn version (v) khớp. Xem các phần Published Router Info và Unpublished Router Info bên dưới.
Nếu Bob có phiên bản RouterInfo cũ hơn của Alice trong netdb của mình, hãy xác minh rằng static key trong router info là giống nhau ở cả hai, nếu có, và nếu phiên bản cũ hơn ít hơn XXX tuổi (xem thời gian xoay key bên dưới)
Bob phải xác thực rằng khóa tĩnh của Alice là một điểm hợp lệ trên đường cong tại đây.
Các tùy chọn nên được bao gồm để chỉ định các tham số padding.
Khi có bất kỳ lỗi nào, bao gồm lỗi xác thực AEAD, RI, DH, timestamp, hoặc key, Bob phải dừng xử lý message và đóng kết nối mà không phản hồi. Đây phải là một đóng kết nối bất thường (TCP RST).
Để tạo điều kiện thuận lợi cho việc bắt tay nhanh chóng, các triển khai phải đảm bảo rằng Alice đệm và sau đó xả toàn bộ nội dung của thông điệp thứ ba cùng một lúc, bao gồm cả hai khung AEAD. Điều này làm tăng khả năng dữ liệu sẽ được chứa trong một gói TCP duy nhất (trừ khi bị phân đoạn bởi hệ điều hành hoặc middlebox), và được Bob nhận tất cả cùng một lúc. Điều này cũng để đảm bảo hiệu quả và đảm bảo tính hiệu quả của việc đệm ngẫu nhiên.
Message 3 part 2 frame length: Độ dài của frame này (bao gồm MAC) được Alice gửi trong message 1. Xem message đó để biết các lưu ý quan trọng về việc để đủ chỗ cho padding.
Nội dung frame của Message 3 part 2: Định dạng của frame này giống với định dạng của các frame trong data phase, ngoại trừ việc độ dài của frame được Alice gửi trong message 1. Xem bên dưới để biết định dạng frame của data phase. Frame phải chứa từ 1 đến 3 block theo thứ tự sau:
- Alice’s Router Info block (bắt buộc)
- Options block (tùy chọn)
- Padding block (tùy chọn) Frame này không bao giờ được chứa bất kỳ loại block nào khác.
Phần đệm của Message 3 part 2 không bắt buộc nếu Alice nối thêm một data phase frame (có thể chứa đệm tùy chọn) vào cuối message 3 và gửi cả hai cùng lúc, vì nó sẽ xuất hiện như một luồng byte lớn đối với người quan sát. Vì Alice thường sẽ có một I2NP message để gửi cho Bob (nhưng không phải lúc nào cũng vậy) (đó là lý do cô ấy kết nối với anh ấy), đây là cách triển khai được khuyến nghị, để đảm bảo hiệu quả và tính hiệu quả của random padding.
Tổng độ dài của cả hai AEAD frame Message 3 (phần 1 và 2) là 65535 byte; phần 1 là 48 byte nên độ dài frame tối đa của phần 2 là 65487; độ dài plaintext tối đa của phần 2 không bao gồm MAC là 65471.
Key Derivation Function (KDF) (for data phase)
Giai đoạn dữ liệu sử dụng đầu vào dữ liệu liên kết có độ dài bằng không.
KDF tạo ra hai khóa mã hóa k_ab và k_ba từ chaining key ck, sử dụng HMAC-SHA256(key, data) như được định nghĩa trong RFC-2104. Đây là hàm Split(), chính xác như được định nghĩa trong đặc tả Noise.
ck = from handshake phase
// k_ab, k_ba = HKDF(ck, zerolen)
// ask_master = HKDF(ck, zerolen, info="ask")
// zerolen is a zero-length byte array
temp_key = HMAC-SHA256(ck, zerolen)
// overwrite the chaining key in memory, no longer needed
ck = (all zeros)
// Output 1
// cipher key, for Alice transmits to Bob (Noise doesn't make clear which is which, but Java code does)
k_ab = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// cipher key, for Bob transmits to Alice (Noise doesn't make clear which is which, but Java code does)
k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)).
KDF for SipHash for length field:
Generate an Additional Symmetric Key (ask) for SipHash
SipHash uses two 8-byte keys (big endian) and 8 byte IV for first data.
// "ask" is 3 bytes, US-ASCII, no null termination
ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01))
// sip_master = HKDF(ask_master, h || "siphash")
// "siphash" is 7 bytes, US-ASCII, no null termination
// overwrite previous temp_key in memory
// h is from KDF for message 3 part 2
temp_key = HMAC-SHA256(ask_master, h || "siphash")
// overwrite ask_master in memory, no longer needed
ask_master = (all zeros)
sip_master = HMAC-SHA256(temp_key, byte(0x01))
Alice to Bob SipHash k1, k2, IV:
// sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen)
// overwrite previous temp_key in memory
temp_key = HMAC-SHA256(sip_master, zerolen)
// overwrite sip_master in memory, no longer needed
sip_master = (all zeros)
sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)).
sipk1_ab = sipkeys_ab[0:7], little endian
sipk2_ab = sipkeys_ab[8:15], little endian
sipiv_ab = sipkeys_ab[16:23]
Bob to Alice SipHash k1, k2, IV:
sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02)).
sipk1_ba = sipkeys_ba[0:7], little endian
sipk2_ba = sipkeys_ba[8:15], little endian
sipiv_ba = sipkeys_ba[16:23]
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
4) Data Phase
Noise payload: Như định nghĩa bên dưới, bao gồm random padding Non-noise payload: không có
Bắt đầu từ phần thứ 2 của thông điệp 3, tất cả các thông điệp đều nằm bên trong một “khung” ChaChaPoly được xác thực và mã hóa với độ dài bị xáo trộn hai byte được đặt ở đầu. Tất cả padding đều nằm bên trong khung. Bên trong khung là một định dạng chuẩn với không hoặc nhiều “block”. Mỗi block có một loại một byte và độ dài hai byte. Các loại bao gồm ngày/giờ, thông điệp I2NP, tùy chọn, kết thúc, và padding.
Lưu ý: Bob có thể, nhưng không bắt buộc, gửi RouterInfo của mình cho Alice như tin nhắn đầu tiên gửi đến Alice trong giai đoạn dữ liệu.
(Đặc Tính Bảo Mật Payload)
XK(s, rs): Authentication Confidentiality
<- 2 5
-> 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy.
This payload is encrypted based on an ephemeral-ephemeral DH as well as
an ephemeral-static DH with the recipient's static key pair.
Assuming the ephemeral private keys are secure, and the recipient is not being actively impersonated
by an attacker that has stolen its static private key, this payload cannot be decrypted.
2) DPI Ngoại tuyến
Để đảm bảo hiệu quả và giảm thiểu khả năng nhận diện trường độ dài, các triển khai phải đảm bảo rằng bên gửi đệm và sau đó xả toàn bộ nội dung của các thông điệp dữ liệu cùng một lúc, bao gồm trường độ dài và khung AEAD. Điều này tăng khả năng dữ liệu sẽ được chứa trong một gói TCP duy nhất (trừ khi bị phân đoạn bởi OS hoặc middlebox), và được bên kia nhận cùng một lúc. Điều này cũng nhằm mục đích hiệu quả và đảm bảo tính hiệu quả của việc đệm ngẫu nhiên.
Router có thể chọn chấm dứt phiên khi xảy ra lỗi AEAD, hoặc có thể tiếp tục cố gắng giao tiếp. Nếu tiếp tục, router nên chấm dứt sau các lỗi lặp lại.
SipHash obfuscated length
Tham khảo: SipHash
Khi cả hai bên đã hoàn thành quá trình bắt tay, họ truyền tải các payload sau đó được mã hóa và xác thực trong các “frame” ChaChaPoly.
Mỗi frame được đứng trước bởi một trường độ dài hai byte, big endian. Độ dài này chỉ định số byte frame đã mã hóa sẽ theo sau, bao gồm cả MAC. Để tránh truyền các trường độ dài có thể nhận dạng trong luồng, độ dài frame được làm mờ bằng cách XOR với một mask được tạo từ SipHash, như được khởi tạo từ KDF của giai đoạn dữ liệu. Lưu ý rằng hai hướng có các khóa SipHash và IV duy nhất từ KDF.
sipk1, sipk2 = The SipHash keys from the KDF. (two 8-byte long integers)
IV[0] = sipiv = The SipHash IV from the KDF. (8 bytes)
length is big endian.
For each frame:
IV[n] = SipHash-2-4(sipk1, sipk2, IV[n-1])
Mask[n] = First 2 bytes of IV[n]
obfuscatedLength = length ^ Mask[n]
The first length output will be XORed with with IV[1].
Bên nhận có các khóa SipHash và IV giống hệt nhau. Việc giải mã độ dài được thực hiện bằng cách tạo ra mask được sử dụng để làm mờ độ dài và thực hiện phép XOR với digest đã được cắt ngắn để có được độ dài của frame. Độ dài frame là tổng độ dài của frame đã mã hóa bao gồm cả MAC.
Công việc tương lai
- Nếu bạn sử dụng một hàm thư viện SipHash trả về số nguyên long không dấu, hãy sử dụng hai byte ít quan trọng nhất làm Mask. Chuyển đổi số nguyên long thành IV tiếp theo dưới dạng little endian.
Mã hóa có xác thực
+----+----+----+----+----+----+----+----+
|obf size | |
+----+----+ +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ key is k_ab for Alice to Bob +
| key is k_ba for Bob to Alice |
+ as defined in KDF for data phase +
| n starts at 0 and increments |
+ for each frame in that direction +
| no associated data |
+ 16 bytes minimum +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
obf size :: 2 bytes length obfuscated with SipHash
when de-obfuscated: 16 - 65535
Minimum size including length field is 18 bytes.
Maximum size including length field is 65537 bytes.
Obfuscated length is 2 bytes.
Maximum ChaChaPoly frame is 65535 bytes.
ChaCha20/Poly1305
Có không hoặc nhiều khối trong frame được mã hóa. Mỗi khối chứa một định danh một byte, một độ dài hai byte, và không hoặc nhiều byte dữ liệu.
Để có tính mở rộng, các receiver phải bỏ qua các block có định danh không xác định và coi chúng như padding.
Dữ liệu được mã hóa tối đa 65535 byte, bao gồm header xác thực 16-byte, do đó dữ liệu chưa mã hóa tối đa là 65519 byte.
(Thẻ xác thực Poly1305 không được hiển thị):
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
~ . . . ~
blk :: 1 byte
0 for datetime
1 for options
2 for RouterInfo
3 for I2NP message
4 for termination
224-253 reserved for experimental features
254 for padding
255 reserved for future extension
size :: 2 bytes, big endian, size of data to follow, 0 - 65516
data :: the data
Maximum ChaChaPoly frame is 65535 bytes.
Poly1305 tag is 16 bytes
Maximum total block size is 65519 bytes
Maximum single block size is 65519 bytes
Block type is 1 byte
Block length is 2 bytes
Maximum single block data size is 65516 bytes.
Block Ordering Rules
Trong handshake message 3 phần 2, thứ tự phải là: RouterInfo, theo sau bởi Options nếu có, theo sau bởi Padding nếu có. Không được phép có các block khác.
Trong giai đoạn dữ liệu, thứ tự không được chỉ định cụ thể, ngoại trừ các yêu cầu sau: Padding, nếu có, phải là khối cuối cùng. Termination, nếu có, phải là khối cuối cùng trừ Padding.
Có thể có nhiều khối I2NP trong một frame duy nhất. Không được phép có nhiều khối Padding trong một frame duy nhất. Các loại khối khác có thể sẽ không có nhiều khối trong một frame duy nhất, nhưng điều này không bị cấm.
Xử Lý Lỗi AEAD
Trường hợp đặc biệt cho đồng bộ hóa thời gian:
+----+----+----+----+----+----+----+
| 0 | 4 | timestamp |
+----+----+----+----+----+----+----+
blk :: 0
size :: 2 bytes, big endian, value = 4
timestamp :: Unix timestamp, unsigned seconds.
Wraps around in 2106
Hàm Dẫn Xuất Khóa (KDF) (cho thông điệp bắt tay 1)
Truyền các tùy chọn đã cập nhật. Các tùy chọn bao gồm: Padding tối thiểu và tối đa.
Khối tùy chọn sẽ có độ dài thay đổi.
+----+----+----+----+----+----+----+----+
| 1 | size |tmin|tmax|rmin|rmax|tdmy|
+----+----+----+----+----+----+----+----+
|tdmy| rdmy | tdelay | rdelay | |
~----+----+----+----+----+----+----+ ~
| more_options |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 1
size :: 2 bytes, big endian, size of options to follow, 12 bytes minimum
tmin, tmax, rmin, rmax :: requested padding limits
tmin and rmin are for desired resistance to traffic analysis.
tmax and rmax are for bandwidth limits.
tmin and tmax are the transmit limits for the router sending this options block.
rmin and rmax are the receive limits for the router sending this options block.
Each is a 4.4 fixed-point float representing 0 to 15.9375
(or think of it as an unsigned 8-bit integer divided by 16.0).
This is the ratio of padding to data. Examples:
Value of 0x00 means no padding
Value of 0x01 means add 6 percent padding
Value of 0x10 means add 100 percent padding
Value of 0x80 means add 800 percent (8x) padding
Alice and Bob will negotiate the minimum and maximum in each direction.
These are guidelines, there is no enforcement.
Sender should honor receiver's maximum.
Sender may or may not honor receiver's minimum, within bandwidth constraints.
tdmy: Max dummy traffic willing to send, 2 bytes big endian, bytes/sec average
rdmy: Requested dummy traffic, 2 bytes big endian, bytes/sec average
tdelay: Max intra-message delay willing to insert, 2 bytes big endian, msec average
rdelay: Requested intra-message delay, 2 bytes big endian, msec average
Padding distribution specified as additional parameters?
Random delay specified as additional parameters?
more_options :: Format TBD
1) SessionRequest
- Định dạng tùy chọn sẽ được xác định sau (TBD).
- Đàm phán tùy chọn sẽ được xác định sau (TBD).
RouterInfo
Chuyển RouterInfo của Alice cho Bob. Được sử dụng trong thông điệp bắt tay 3 phần 2. Chuyển RouterInfo của Alice cho Bob, hoặc của Bob cho Alice. Được sử dụng tùy chọn trong giai đoạn dữ liệu.
+----+----+----+----+----+----+----+----+
| 2 | size |flg | RouterInfo |
+----+----+----+----+ +
| (Alice RI in handshake msg 3 part 2) |
~ (Alice, Bob, or third-party ~
| RI in data phase) |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 2
size :: 2 bytes, big endian, size of flag + router info to follow
flg :: 1 byte flags
bit order: 76543210
bit 0: 0 for local store, 1 for flood request
bits 7-1: Unused, set to 0 for future compatibility
routerinfo :: Alice's or Bob's RouterInfo
Notes
Khi được sử dụng trong giai đoạn data, bên nhận (Alice hoặc Bob) phải xác thực rằng đó là cùng một Router Hash như đã gửi ban đầu (đối với Alice) hoặc đã gửi đến (đối với Bob). Sau đó, xử lý nó như một I2NP DatabaseStore Message cục bộ. Xác thực chữ ký, xác thực timestamp gần đây hơn, và lưu trữ trong netDb cục bộ. Nếu flag bit 0 là 1, và bên nhận là floodfill, xử lý nó như một DatabaseStore Message với reply token khác không, và flood nó đến các floodfill gần nhất.
Router Info KHÔNG được nén bằng gzip (không giống như trong DatabaseStore Message, nơi nó được nén)
Flooding không được yêu cầu trừ khi có các RouterAddresses đã được xuất bản trong RouterInfo. Router nhận không được flood RouterInfo trừ khi có các RouterAddresses đã được xuất bản trong đó.
Các nhà phát triển phải đảm bảo rằng khi đọc một block, dữ liệu bị lỗi hoặc độc hại sẽ không gây ra việc đọc vượt quá giới hạn sang block tiếp theo.
Giao thức này không cung cấp xác nhận rằng RouterInfo đã được nhận, lưu trữ hoặc flood (trong cả giai đoạn handshake hoặc dữ liệu). Nếu muốn có xác nhận và receiver là floodfill, sender nên gửi một DatabaseStoreMessage I2NP tiêu chuẩn với reply token.
Issues
Cũng có thể được sử dụng trong giai đoạn dữ liệu, thay vì một I2NP DatabaseStoreMessage. Ví dụ, Bob có thể sử dụng nó để bắt đầu giai đoạn dữ liệu.
Có được phép cho cái này chứa RI cho các router khác ngoài người khởi tạo, như một sự thay thế chung cho DatabaseStoreMessages, ví dụ như để flooding bởi floodfills?
Hàm Dẫn Xuất Khóa (KDF) (cho thông điệp handshake 2 và thông điệp 3 phần 1)
Một thông điệp I2NP đơn lẻ với header đã được sửa đổi. Các thông điệp I2NP không được phân mảnh qua các khối hoặc qua các khung ChaChaPoly.
Điều này sử dụng 9 byte đầu tiên từ header I2NP NTCP tiêu chuẩn, và loại bỏ 7 byte cuối của header, như sau: cắt ngắn thời gian hết hạn từ 8 xuống 4 byte, loại bỏ 2 byte độ dài (sử dụng kích thước khối - 9), và loại bỏ checksum SHA256 một byte.
+----+----+----+----+----+----+----+----+
| 3 | size |type| msg id |
+----+----+----+----+----+----+----+----+
| short exp | message |
+----+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 3
size :: 2 bytes, big endian, size of type + msg id + exp + message to follow
I2NP message body size is (size - 9).
type :: 1 byte, I2NP msg type, see I2NP spec
msg id :: 4 bytes, big endian, I2NP message ID
short exp :: 4 bytes, big endian, I2NP message expiration, Unix timestamp, unsigned seconds.
Wraps around in 2106
message :: I2NP message body
Notes
- Các nhà phát triển phải đảm bảo rằng khi đọc một block, dữ liệu bị lỗi hoặc độc hại sẽ không gây ra việc đọc vượt quá giới hạn sang block tiếp theo.
2) SessionCreated
Noise khuyên nên có thông báo chấm dứt rõ ràng. NTCP gốc không có thông báo này. Ngắt kết nối. Đây phải là khối không phải padding cuối cùng trong frame.
+----+----+----+----+----+----+----+----+
| 4 | size | valid data frames |
+----+----+----+----+----+----+----+----+
received | rsn| addl data |
+----+----+----+----+ +
~ . . . ~
+----+----+----+----+----+----+----+----+
blk :: 4
size :: 2 bytes, big endian, value = 9 or more
valid data frames received :: The number of valid AEAD data phase frames received
(current receive nonce value)
0 if error occurs in handshake phase
8 bytes, big endian
rsn :: reason, 1 byte:
0: normal close or unspecified
1: termination received
2: idle timeout
3: router shutdown
4: data phase AEAD failure
5: incompatible options
6: incompatible signature type
7: clock skew
8: padding violation
9: AEAD framing error
10: payload format error
11: message 1 error
12: message 2 error
13: message 3 error
14: intra-frame read timeout
15: RI signature verification fail
16: s parameter missing, invalid, or mismatched in RouterInfo
17: banned
addl data :: optional, 0 or more bytes, for future expansion, debugging,
or reason text.
Format unspecified and may vary based on reason code.
Notes
Không phải tất cả các lý do đều thực sự được sử dụng, tùy thuộc vào cách triển khai. Các lỗi handshake thường sẽ dẫn đến đóng kết nối bằng TCP RST thay vì. Xem ghi chú trong các phần thông điệp handshake ở trên. Các lý do bổ sung được liệt kê là để đảm bảo tính nhất quán, ghi log, gỡ lỗi, hoặc trong trường hợp chính sách thay đổi.
Padding
Đây là để padding bên trong các AEAD frame. Padding cho message 1 và 2 nằm bên ngoài các AEAD frame. Tất cả padding cho message 3 và giai đoạn dữ liệu đều nằm bên trong các AEAD frame.
Padding bên trong AEAD nên tuân thủ gần đúng các tham số đã thỏa thuận. Bob đã gửi các tham số tx/rx min/max được yêu cầu của mình trong message 2. Alice đã gửi các tham số tx/rx min/max được yêu cầu của mình trong message 3. Các tùy chọn được cập nhật có thể được gửi trong giai đoạn data. Xem thông tin khối options ở trên.
Nếu có mặt, đây phải là block cuối cùng trong frame.
+----+----+----+----+----+----+----+----+
|254 | size | padding |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 254
size :: 2 bytes, big endian, size of padding to follow
padding :: random data
Notes
- Các chiến lược padding chưa được xác định (TBD).
- Padding tối thiểu chưa được xác định (TBD).
- Các frame chỉ chứa padding được cho phép.
- Giá trị mặc định của padding chưa được xác định (TBD).
- Xem khối options để biết thông tin về thương lượng tham số padding
- Xem khối options để biết thông tin về các tham số padding tối thiểu/tối đa
- Noise giới hạn tin nhắn ở mức 64KB. Nếu cần nhiều padding hơn, hãy gửi nhiều frame.
- Phản hồi của router khi vi phạm padding đã thương lượng phụ thuộc vào cách triển khai.
Other block types
Các triển khai nên bỏ qua các loại block không xác định để tương thích tiến về phía trước, ngoại trừ trong message 3 phần 2, nơi không cho phép các block không xác định.
Future work
- Độ dài padding có thể được quyết định trên cơ sở từng thông điệp và ước tính phân bố độ dài, hoặc nên thêm độ trễ ngẫu nhiên. Các biện pháp đối phó này được bao gồm để chống lại DPI, vì kích thước thông điệp có thể tiết lộ rằng lưu lượng I2P đang được truyền tải bởi giao thức vận chuyển. Lược đồ padding chính xác là một lĩnh vực nghiên cứu trong tương lai, Phụ lục A cung cấp thêm thông tin về chủ đề này.
5) Termination
Các kết nối có thể được chấm dứt thông qua việc đóng TCP socket bình thường hoặc bất thường, hoặc, như Noise khuyến nghị, thông qua một thông điệp chấm dứt rõ ràng. Thông điệp chấm dứt rõ ràng được định nghĩa trong giai đoạn dữ liệu ở trên.
Khi có bất kỳ sự kết thúc bình thường hoặc bất thường nào, các router nên xóa sạch mọi dữ liệu tạm thời trong bộ nhớ, bao gồm các khóa tạm thời handshake, khóa mã hóa đối xứng, và thông tin liên quan.
Published Router Info
Mã hóa cho phần 1 của thông điệp handshake 3, sử dụng KDF của thông điệp 2)
RouterAddress được công bố (một phần của RouterInfo) sẽ có định danh giao thức là “NTCP” hoặc “NTCP2”.
RouterAddress phải chứa các tùy chọn “host” và “port”, như trong giao thức NTCP hiện tại.
RouterAddress phải chứa ba tùy chọn để chỉ ra hỗ trợ NTCP2:
s=(Base64 key) Khóa công khai tĩnh Noise hiện tại (s) cho RouterAddress này. Được mã hóa Base 64 sử dụng bảng chữ cái Base 64 chuẩn của I2P. 32 byte ở dạng nhị phân, 44 byte ở dạng mã hóa Base 64, khóa công khai X25519 little-endian.
i=(Base64 IV) IV hiện tại để mã hóa giá trị X trong thông điệp 1 cho RouterAddress này. Được mã hóa Base 64 sử dụng bảng chữ cái Base 64 chuẩn của I2P. 16 byte ở dạng nhị phân, 24 byte khi được mã hóa Base 64, big-endian.
v=2 Phiên bản hiện tại (2). Khi được công bố dưới dạng “NTCP”, hỗ trợ bổ sung cho phiên bản 1 được ngụ ý. Hỗ trợ cho các phiên bản tương lai sẽ sử dụng các giá trị phân tách bằng dấu phẩy, ví dụ v=2,3 Việc triển khai nên xác minh tính tương thích, bao gồm nhiều phiên bản nếu có dấu phẩy. Các phiên bản phân tách bằng dấu phẩy phải theo thứ tự số.
Alice phải xác minh rằng cả ba tùy chọn đều có mặt và hợp lệ trước khi kết nối bằng giao thức NTCP2.
Khi được xuất bản dưới dạng “NTCP” với các tùy chọn “s”, “i”, và “v”, router phải chấp nhận các kết nối đến trên host và port đó cho cả hai giao thức NTCP và NTCP2, và tự động phát hiện phiên bản giao thức.
Khi được công bố với tùy chọn “NTCP2” cùng với các tùy chọn “s”, “i”, và “v”, router sẽ chấp nhận các kết nối đến trên host và port đó chỉ dành cho giao thức NTCP2.
Nếu một router hỗ trợ cả kết nối NTCP1 và NTCP2 nhưng không triển khai phát hiện phiên bản tự động cho các kết nối đến, nó phải quảng bá cả địa chỉ “NTCP” và “NTCP2”, và chỉ bao gồm các tùy chọn NTCP2 trong địa chỉ “NTCP2”. Router nên đặt giá trị cost thấp hơn (ưu tiên cao hơn) trong địa chỉ “NTCP2” so với địa chỉ “NTCP”, để NTCP2 được ưu tiên.
Nếu nhiều NTCP2 RouterAddresses (dưới dạng “NTCP” hoặc “NTCP2”) được xuất bản trong cùng một RouterInfo (cho các địa chỉ IP hoặc cổng bổ sung), tất cả các địa chỉ chỉ định cùng một cổng phải chứa các tùy chọn và giá trị NTCP2 giống hệt nhau. Đặc biệt, tất cả phải chứa cùng static key và iv.
Hàm Dẫn Xuất Khóa (KDF) (cho handshake message 3 phần 2)
Nếu Alice không công bố địa chỉ NTCP2 của mình (dưới dạng “NTCP” hoặc “NTCP2”) cho các kết nối đến, cô ấy phải công bố một địa chỉ router “NTCP2” chỉ chứa static key và phiên bản NTCP2 của mình, để Bob có thể xác thực key sau khi nhận RouterInfo của Alice trong message 3 part 2.
s=(Base64 key) Như đã định nghĩa ở trên cho các địa chỉ đã xuất bản.
v=2 Như đã định nghĩa ở trên cho các địa chỉ đã được công bố.
Địa chỉ router này sẽ không chứa các tùy chọn “i”, “host” hoặc “port”, vì chúng không cần thiết cho các kết nối NTCP2 ra ngoài. Chi phí được công bố cho địa chỉ này không thực sự quan trọng, vì nó chỉ dành cho kết nối vào; tuy nhiên, có thể hữu ích cho các router khác nếu chi phí được đặt cao hơn (ưu tiên thấp hơn) so với các địa chỉ khác. Giá trị được đề xuất là 14.
Alice cũng có thể đơn giản thêm các tùy chọn “s” và “v” vào một địa chỉ “NTCP” đã được xuất bản hiện có.
3) SessionConfirmed
Do việc cache các RouterInfo, các router không được xoay khóa công khai tĩnh hoặc IV trong khi router đang hoạt động, bất kể có trong địa chỉ được công bố hay không. Các router phải lưu trữ bền vững khóa và IV này để tái sử dụng sau khi khởi động lại ngay lập tức, để các kết nối đến sẽ tiếp tục hoạt động và thời gian khởi động lại không bị lộ. Các router phải lưu trữ bền vững, hoặc xác định bằng cách khác, thời gian tắt-máy lần cuối, để thời gian ngừng hoạt động trước đó có thể được tính toán khi khởi động.
Tùy thuộc vào mối quan tâm về việc tiết lộ thời gian khởi động lại, các router có thể thay đổi khóa hoặc IV này khi khởi động nếu router trước đó đã tắt trong một thời gian (ít nhất vài giờ).
Nếu router có bất kỳ RouterAddresses NTCP2 đã được xuất bản nào (như NTCP hoặc NTCP2), thời gian downtime tối thiểu trước khi luân phiên nên dài hơn nhiều, ví dụ một tháng, trừ khi địa chỉ IP cục bộ đã thay đổi hoặc router “rekeys”.
Nếu router có bất kỳ RouterAddresses SSU đã xuất bản nào, nhưng không có NTCP2 (như NTCP hoặc NTCP2) thì thời gian ngừng hoạt động tối thiểu trước khi luân chuyển nên dài hơn, ví dụ một ngày, trừ khi địa chỉ IP cục bộ đã thay đổi hoặc router “rekeys”. Điều này áp dụng ngay cả khi địa chỉ SSU đã xuất bản có introducers.
Nếu router không có bất kỳ RouterAddresses đã xuất bản nào (NTCP, NTCP2, hoặc SSU), thời gian downtime tối thiểu trước khi xoay vòng có thể ngắn chỉ hai giờ, ngay cả khi địa chỉ IP thay đổi, trừ khi router thực hiện “rekeys”.
Nếu router “rekeys” sang một Router Hash khác, nó cũng nên tạo ra một noise key và IV mới.
Các triển khai phải nhận thức rằng việc thay đổi static public key hoặc IV sẽ cấm các kết nối NTCP2 đến từ các router đã cache một RouterInfo cũ hơn. Việc xuất bản RouterInfo, lựa chọn tunnel peer (bao gồm cả OBGW và IB closest hop), lựa chọn zero-hop tunnel, lựa chọn transport, và các chiến lược triển khai khác phải tính đến điều này.
Việc luân chuyển IV tuân theo các quy tắc giống hệt như luân chuyển khóa, ngoại trừ việc IV chỉ có mặt trong các RouterAddresses đã được công bố, vì vậy không có IV cho các router ẩn hoặc bị tường lửa chặn. Nếu có bất kỳ thay đổi nào (phiên bản, khóa, tùy chọn?) thì khuyến nghị IV cũng nên thay đổi theo.
Lưu ý: Thời gian ngừng hoạt động tối thiểu trước khi tái tạo khóa có thể được điều chỉnh để đảm bảo tình trạng mạng lưới, và để ngăn chặn việc reseeding bởi một router đã ngừng hoạt động trong một khoảng thời gian vừa phải.
Identity Hiding
Khả năng chối bỏ không phải là mục tiêu. Xem tổng quan ở trên.
Mỗi mẫu được gán các thuộc tính mô tả tính bảo mật được cung cấp cho khóa công khai tĩnh của bên khởi tạo và cho khóa công khai tĩnh của bên phản hồi. Các giả định cơ bản là các khóa riêng tư tạm thời được bảo mật, và các bên sẽ hủy bỏ quá trình bắt tay nếu họ nhận được khóa công khai tĩnh từ bên kia mà họ không tin tưởng.
Phần này chỉ xem xét việc rò rỉ danh tính thông qua các trường khóa công khai tĩnh trong handshake. Tất nhiên, danh tính của những người tham gia Noise có thể bị lộ thông qua các phương tiện khác, bao gồm các trường payload, phân tích lưu lượng, hoặc metadata như địa chỉ IP.
Alice: (8) Được mã hóa với tính bảo mật chuyển tiếp (forward secrecy) đến một bên đã được xác thực.
Bob: (3) Không được truyền, nhưng kẻ tấn công thụ động có thể kiểm tra các ứng viên cho private key của người phản hồi và xác định xem ứng viên đó có đúng hay không.
Bob công bố khóa công khai tĩnh của mình trong netDb. Alice có thể hoặc có thể không?
Issues
- Nếu Bob thay đổi static key của mình, có thể fallback về pattern “XX” không?
Khung Giao thức Noise
Khi được công bố là “NTCP”, router phải tự động phát hiện phiên bản giao thức cho các kết nối đến.
Việc phát hiện này phụ thuộc vào cách triển khai, nhưng đây là một số hướng dẫn chung.
Để phát hiện phiên bản của một kết nối NTCP đến, Bob thực hiện như sau:
Chờ ít nhất 64 bytes (kích thước tối thiểu của NTCP2 message 1)
Nếu dữ liệu nhận được ban đầu là 288 bytes trở lên, kết nối đến là phiên bản 1.
Nếu ít hơn 288 bytes, thì
Chờ một khoảng thời gian ngắn để có thêm dữ liệu (chiến lược tốt trước khi NTCP2 được áp dụng rộng rãi) nếu nhận được ít nhất 288 tổng cộng, đó là NTCP 1.
Thử các giai đoạn đầu của việc giải mã như phiên bản 2, nếu thất bại, đợi một thời gian ngắn để có thêm dữ liệu (chiến lược tốt sau khi NTCP2 được áp dụng rộng rãi)
- Decrypt the first 32 bytes (the X key) of the SessionRequest packet using AES-256 with key RH_B. - Verify a valid point on the curve. If it fails, wait a short time for more data for NTCP 1 - Verify the AEAD frame. If it fails, wait a short time for more data for NTCP 1
Lưu ý rằng các thay đổi hoặc chiến lược bổ sung có thể được khuyến nghị nếu chúng tôi phát hiện các cuộc tấn công phân đoạn TCP đang hoạt động trên NTCP 1.
Để tạo điều kiện thuận lợi cho việc phát hiện phiên bản nhanh chóng và handshaking, các triển khai phải đảm bảo rằng Alice đệm và sau đó flush toàn bộ nội dung của thông điệp đầu tiên cùng một lúc, bao gồm cả padding. Điều này tăng khả năng dữ liệu sẽ được chứa trong một gói TCP duy nhất (trừ khi bị phân đoạn bởi OS hoặc middlebox), và được Bob nhận tất cả cùng một lúc. Điều này cũng nhằm mục đích hiệu quả và đảm bảo tính hiệu quả của random padding. Điều này áp dụng cho cả NTCP và NTCP2 handshake.
Bổ sung vào Framework
Nếu cả Alice và Bob đều hỗ trợ NTCP2, Alice nên kết nối với NTCP2.
Nếu Alice không thể kết nối với Bob bằng NTCP2 vì bất kỳ lý do gì, kết nối sẽ thất bại. Alice không được thử lại bằng NTCP 1.
Fallback về pattern XX nếu Bob thay đổi keys của mình? Điều này sẽ yêu cầu một type byte được prepended?
“Fall forward” sang pattern KK nếu Alice kết nối lại, giả sử Bob vẫn còn giữ static key của cô ấy? Điều này không tiết kiệm bất kỳ round trip nào và sử dụng 4 DH rounds so với 3 cho XK. Có lẽ là không.
KK(s, rs):
-> s
<- s
...
-> e, es, ss
<- e, ee, se
Các Nguyên Thủy Mật Mã Học Mới cho I2P
Phần này thảo luận về một cuộc tấn công nhằm vào các lược đồ padding điển hình, cho phép kẻ tấn công khám phá phân bố xác suất của độ dài các thông điệp chưa được padding, chỉ bằng cách quan sát độ dài của các thông điệp đã được padding. Gọi N là một biến ngẫu nhiên mô tả số byte chưa được padding, và P tương tự cho số byte padding. Kích thước thông điệp tổng cộng là N + P.
Giả sử rằng đối với kích thước không padding là n, ít nhất P_min(n) >= 0 và nhiều nhất P_max(n) >= P_min(n) byte padding được thêm vào trong một scheme padding. Scheme hiển nhiên sử dụng padding có độ dài P được chọn ngẫu nhiên đồng đều:
Pr[P = p | N = n] = 1 / (P_max(n) - P_min(n)) if P_min(n) <= p <= P_max(n),
0 otherwise.
Một phương pháp padding ngây thơ sẽ chỉ đơn giản đảm bảo rằng kích thước của thông điệp được padding không vượt quá N_max:
P_max(n) = N_max - n, n <= N_max
P_min(n) = 0.
Tuy nhiên, điều này làm rò rỉ thông tin về chiều dài chưa được đệm.
Kẻ tấn công có thể dễ dàng ước tính Pr[x <= N + P <= y], ví dụ bằng cách sử dụng biểu đồ tần suất.
- Từ đây, anh ta cũng có thể cố gắng ước tính
Pr[n_1 <= N <= n_2], thực sự:
Pr[N + P = m] = Σ_n Pr[N = n] Pr[P = m - n | N = n].
Trong sơ đồ đơn giản,
Pr[N + P = m] = Σ_{n <= m} Pr[N = n] / (N_max - n).
Điều này khá rõ ràng, như trước khi thực hiện phép tính trên, rằng việc này làm rò rỉ thông tin về Pr[N = n]: nếu chiều dài của các packet hầu như luôn lớn hơn m, thì N + P <= m sẽ hầu như không bao giờ được quan sát thấy. Tuy nhiên đây không phải là vấn đề lớn nhất, mặc dù việc có thể quan sát chiều dài thông điệp tối thiểu có thể được coi là một vấn đề riêng biệt.
Một vấn đề lớn hơn là có thể xác định chính xác Pr[N = n]:
Pr[N + P = m] - Pr[N + P = m-1] = Pr[N = m] / (N_max - m),
tức là
Pr[N = n] = (N_max - n)(Pr[N + P = n] - Pr[N + P = n - 1])
Để phân biệt NTCP2, kẻ tấn công có thể sử dụng bất kỳ cách nào sau đây:
Ước tính
Pr[kB <= N <= (k + 1)B - 1]cho các số nguyên dương k. Nó sẽ luôn bằng không đối với NTCP2.Ước tính
Pr[N = kB]và so sánh với profile I2P tiêu chuẩn.
Cuộc tấn công đơn giản này do đó phá hủy một phần mục đích của padding, vốn cố gắng che giấu phân phối kích thước của các thông điệp chưa được padding. Số lượng thông điệp mà kẻ tấn công phải quan sát để phân biệt giao thức phụ thuộc vào độ chính xác mong muốn và vào kích thước tối thiểu và tối đa của thông điệp chưa được padding xuất hiện trong thực tế. Lưu ý rằng việc thu thập nhiều thông điệp là dễ dàng đối với kẻ tấn công, vì họ có thể sử dụng tất cả lưu lượng được gửi từ và đến cổng cụ thể mà mục tiêu đang sử dụng.
Trong một số dạng (ví dụ: ước tính Pr[kB <= N <= (k + 1)B - 1]) cuộc tấn công chỉ yêu cầu vài byte bộ nhớ (một số nguyên là đủ) và có thể lập luận rằng cuộc tấn công như vậy có thể được đưa vào nhiều framework DPI tiêu chuẩn nhưng tuy nhiên hơi nâng cao.
Đề xuất này gợi ý sử dụng một trong các biện pháp đối phó sau:
Phát triển một phương án padding thay thế có tính đến phân phối (ước tính) của N bằng cách sử dụng phân phối độ dài padding không đồng nhất. Một phương án padding tốt có thể sẽ yêu cầu duy trì histogram về số lượng block trên mỗi thông điệp.
Thêm độ trễ ngẫu nhiên giữa các phân đoạn (có kích thước ngẫu nhiên) của thông điệp.
Lựa chọn thứ hai được ưa chuộng hơn nói chung, vì nó có thể được sử dụng đồng thời như một biện pháp đối phó chống lại phân tích luồng dữ liệu. Tuy nhiên, những độ trễ như vậy có thể nằm ngoài phạm vi của giao thức NTCP2, do đó lựa chọn thứ nhất, cũng dễ triển khai hơn, có thể được ưa chuộng thay thế.
Ước tính chi phí xử lý
Khả năng chống DPI dựa trên thời gian (thời gian/độ trễ giữa các thông điệp có thể phụ thuộc vào cách triển khai; độ trễ trong thông điệp có thể được đưa vào tại bất kỳ điểm nào, bao gồm cả trước khi gửi random padding chẳng hạn). Độ trễ nhân tạo (cái mà obfs4 gọi là IAT hoặc inter-arrival time) độc lập với chính giao thức.