Ghi chú
Giai đoạn đề xuất đã kết thúc. 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 để lấy 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 diện và tấn công tự động đối với 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. Sau đó, một thông số kỹ thuật đầy đủ về tất cả các thông điệp giao thức được cung cấp. Cuối cùng, địa chỉ bộ định tuyến và nhận diện phiên bản được thảo luận. Một phụ lục thảo luận về một cuộc tấn công chung vào các lược đồ đệm phổ biến cũng được bao gồm, cũng như một phụ lục chứa một số ứng cử viên cho mật mã được xác thực.
Giống như các giao thức truyền tải I2P khác, NTCP2 được định nghĩa duy nhất cho truyền tải điểm-điểm (bộ định tuyến đến bộ định tuyến) các thông điệp I2NP. Nó không phải là một đường ống dữ liệu đa năng.
Độ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 dường như là dữ liệu ngẫu nhiên), do đó ngăn chặn việc nhận diện giao thức thông qua “phân tích nội dung”. Tuy nhiên, nó vẫn dễ bị nhận diện giao thức thông qua “phân tích luồng”. Đó là vì 4 thông điệp đầu tiên (tức là phần bắt tay) có độ dài cố định (288, 304, 448 và 48 byte).
Bằng cách thêm một lượng dữ liệu ngẫu nhiên ngẫu nhiên vào mỗi thông điệp, chúng ta có thể làm cho việc nhận diện trở nên 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. Bất cứ nơi nào phù hợp, các đoạn “công việc trong tương lai” đã được thêm vào để chỉ ra các tính năng còn thiếu hoặc các chủ đề thảo luận.
Mục tiêu thiết kế
Hỗ trợ NTCP phiên bản 1 và 2 trên một cổng duy nhất, tự động phát hiện và công bố như một “giao thức truyền tải” duy nhất (tức là RouterAddress) trong NetDB .
Công bố hỗ trợ phiên bản 1, chỉ phiên bản 2, hoặc cả 1+2 trong NetDB ở một trường riêng biệt, và mặc định là 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 bộ định tuyến 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 họ.
Thêm dữ liệu đệm ngẫu nhiên vào tất cả các thông điệp NTCP bao gồm cả thông điệp bắt tay và dữ liệu (tức là ngụy trang độ dài để tất cả cá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 để cả hai bên yêu cầu độ đệm tối thiểu và tối đa và/hoặc phân phối độ đệm. Chi tiết về phân phối độ đệm phụ thuộc vào triển khai và có thể hoặc không được quy định trong chính giao thức.
Ngụy trang nội dung các thông điệp chưa được mã hóa (1 và 2), đủ để các hộp DPI và chữ ký phần mềm diệt virus 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 một 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 một hàm dẫn xuất khóa thực sự (KDF) thay vì sử dụng kết quả DH như hiện tại?
Thêm “kháng thăm dò” (như Tor gọi); điều này bao gồm khả năng chống lặp lại.
Duy trì trao đổi khóa xác thực hai chiều (2W-AKE). 1W-AKE là không đủ cho ứng dụng của chúng ta.
Tiếp tục sử dụng chữ ký kiểu biến, độ dài biến (từ khóa ký danh bộ định tuyến được công bố) như một phần của xác thực. Dựa vào một 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 tùy chọn/phiên bản vào phần bắt tay để mở rộng trong tương lai.
Thêm khả năng chống lại phân đoạn TCP ác ý của MitM nếu có thể.
Không làm tăng đáng kể CPU cần thiết để 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à loại bỏ kiểm tra Adler.
Rút ngắn và đơn giản hóa tiêu đề I2NP: rút ngắn thời gian hết hạn xuống 4 byte, như trong SSU. Loại bỏ kiểm tra SHA256 một byte bị cắt ngắn.
Nếu có thể, giảm phần bắt tay 4 thông điệp, hai lượt đi xuống còn 3 thông điệp, một lượt đi, như trong SSU . Điều này sẽ yêu cầu chuyển chữ ký của Bob từ thông điệp 4 sang thông điệp 2. Nghiên cứu lý do cho 4 thông điệp trong các lưu trữ email/trạng thái/họp cách đây mười năm.
Tối thiểu hóa chi phí giao thức trước khi đệm. Mặc dù sẽ thêm đệm, và có thể rất nhiều, chi phí trước khi đệm vẫn là chi phí. Các nút băng thông thấp phải có thể sử dụng NTCP2.
Duy trì dấu thời gian để phát hiện lặp lại và lệch.
Tránh bất kỳ vấn đề nào về năm 2038 trong dấu thời gian, phải hoạt động ít nhất đến năm 2106.
Tăng kích thước thông điệp tối đa từ 16K lên 32K hoặc 64K.
Bất kỳ nguyên thủy mật mã mới nào cũng nên có sẵn dễ dàng trong các thư viện để sử dụng trong các triển khai bộ định tuyến Java (1.7), C++ và Go.
Bao gồm đại diện từ các nhà phát triển bộ định tuyến Java, C++ và Go trong thiết kế.
Tối thiểu hóa 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 triển khai).
Mục tiêu không
Kháng DPI hoàn hảo… đó sẽ là các giao thức cắm thêm, Prop109 .
Một giao thức truyền tải dựa trên TLS (hoặc giống HTTPS)… đó sẽ là Prop104 .
Được phép thay đổi mật mã dòng đối xứng.
Kháng DPI dựa trên thời gian (thời gian/delay giữa các thông điệp có thể phụ thuộc vào triển khai; delay trong thông điệp có thể được đưa vào bất kỳ lúc nào, bao gồm cả trước khi gửi dữ liệu đệm ngẫu nhiên, ví dụ). Các delay nhân tạo (những gì obfs4 gọi là IAT hoặc thời gian đến) là độc lập với chính 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 thể được xem xét lại hoặc thảo luận một phần:
Mức độ bảo vệ chống Kiểm tra Gói Sâu (DPI)
Bảo mật Chống Lượng Tử (PQ)
Khả năng phủ nhận
Mục tiêu liên quan
- Triển khai thiết lập kiểm thử NTCP 1/2
Mục tiêu bảo mật
Chúng ta 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 với.
- Mallory, “kẻ trung gian” giữa Alice và Bob.
Tối đa hai người tham gia có thể tham gia vào 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 đề xuất cố gắng cho phép Alice và Bob thỏa thuận 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: Bob hoặc Mallory không biết gì về khóa riêng tĩnh của Alice. Tương tự, Alice không biết gì về khóa riêng 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: khóa phiên đã thỏa thuận vẫn được giữ bí mật trong tương lai, ngay cả khi các 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 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 không dễ dàng để phát hiện rằng Alice và Bob đang tham gia vào giao thức bằng cách sử dụng các kỹ thuật kiểm tra gói sâu (DPI) đơn giản. Xem bên dưới.
Khả năng phủ nhận hạn chế: cả Alice và Bob đều không thể phủ nhận việc tham gia vào giao thức, nhưng nếu một trong hai tiết lộ khóa chung, bên kia có thể phủ nhận tính xác thực của nội dung dữ liệu 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 .
Thảo luận thêm về DPI
Chúng ta giả định hai thành phần DPI:
1) DPI trực tuyến
DPI trực tuyến kiểm tra tất cả các luồng theo thời gian thực. Các kết nối có thể bị chặn hoặc bị can thiệp theo cách khác. Dữ liệu kết nối hoặc siêu dữ liệu 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 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 hàm mật mã thời gian thực nhanh như AES, AEAD và băm, nhưng những cái này quá tốn kém để áp dụng cho hầu hết hoặc tất cả các luồng. Bất kỳ ứng dụng nào của các hoạt động mật mã này sẽ chỉ áp dụng cho các luồng trên các tổ hợp IP/Cổng đã đượ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 hàm mật mã tốn kém 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 diện giao thức bởi DPI trực tuyến.
Khái niệm DPI trực tuyến hoặc “thẳng thắn” được hiểu ở đây bao gồm các khả năng của kẻ 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 các mật mã khối hoặc hàm băm.
Khả năng lưu trữ và so sánh với các thông điệp đã gửi trước đó.
Khả năng sửa đổi, trì hoãn hoặc phân mảnh các gói tin.
Tuy nhiên, DPI trực tuyến được cho là có các hạn chế sau:
Không thể ánh xạ địa chỉ IP thành băm bộ định tuyến. Mặc dù điều này là đơn giản với quyền truy cập thời gian thực vào cơ sở dữ liệu mạng, như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ế đặc biệt để phát hiện I2P. Điều này bao gồm việc tạo “mồi nhử”, ví dụ như bao gồm dữ liệu đệm 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 học máy hoặc các công cụ DPI có thể 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 nội dung, cần đảm bảo rằng tất cả các thông điệp đều không thể phân biệt 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ỉ thêm dữ liệu đệm ngẫu nhiên. Trên thực tế, trong Phụ lục A, các tác giả lập luận rằng một lược đồ đệm ngây thơ (tức là phân bố đề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 đồ đệm thay thế có thể cung cấp sự 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 các độ trễ ngẫu nhiên trong giao thức. Các kỹ thuật như vậy không được bao gồm trong đề xuất này, nhưng chúng cũng có thể giải quyết các vấn đề về độ dài đệm. Tóm lại, đề xuất cung cấp sự bảo vệ tốt chống lại phân tích nội dung (khi các xem xét trong Phụ lục A được tính đến), nhưng chỉ có sự bảo vệ hạn chế chống lại phân tích luồng.
2) DPI ngoại tuyến
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 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 I2P này và các thông số kỹ thuật 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 hàm 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 tại. 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 máy chủ/cổng của các bên, ví dụ như TCP RST. DPI ngoại tuyến có khả năng lặp lại gần thời gian thực (trong vòng vài phút sau khi thiết lập) các thông điệp trước đó (đã sửa đổi hoặc chưa) vì mục đích “thăm dò” hoặc các lý do khác.
Không phải là mục tiêu để ngăn chặn việc nhận diện giao thức bởi DPI ngoại tuyến. Tất cả việc giải mã dữ liệu ngụy trang trong hai thông điệp đầu tiên, được triển khai bởi các bộ định tuyến I2P, cũng có thể được triển khai bởi DPI ngoại tuyến.
Mục tiêu là từ chối các kết nối cố gắng sử dụng việc lặp lại các thông điệp trước đó.
Công việc trong tương lai
Xem xét hành vi của giao thức khi các gói tin bị mất hoặc bị sắp xếp lại bởi một kẻ tấn công. Gần đây có công trình thú vị 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, tính đến các tài liệu hiện có liên quan đến chủ đề.
Thảo luận về tính bảo mật chính thức của giao thức đề xuất, lý tưởng là tính đến mô hình kẻ tấn công DPI.
Khung giao thức Noise
Đề xuất này cung cấp các yêu cầu dựa trên Khung giao thức Noise NOISE (Phiên bản 33, 2017-10-04). Noise có các thuộc tính tương tự như giao thức Station-To-Station, là cơ sở cho giao thức SSU . Trong thuật ngữ của Noise, Alice là người khởi tạo, và Bob là người phản hồi.
NTCP2 dựa trên giao thức Noise Noise_XK_25519_ChaChaPoly_SHA256. (Bộ đị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ỉ 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:
Mẫu bắt tay: XK Alice truyền khóa của cô ấy cho Bob (X) Alice đã biết khóa tĩnh của Bob (K)
Hàm DH: X25519 DH X25519 với độ dài khóa 32 byte như được quy định trong RFC-7748 .
Hàm mật mã: ChaChaPoly AEAD_CHACHA20_POLY1305 như được quy định trong RFC-7539 mục 2.8. Nonce 12 byte, với 4 byte đầu tiên được đặt thành 0.
Hàm băm: SHA256 Băm chuẩn 32 byte, đã được sử dụng rộng rãi trong I2P.
Các bổ sung cho khung giao thức
Đề xuất này định nghĩa các cải tiến sau cho Noise_XK_25519_ChaChaPoly_SHA256. Những cải tiến này nói chung tuân theo các hướng dẫn trong NOISE mục 13.
Các khóa tạm thời rõ ràng được ngụy trang bằng mã hóa AES sử dụng khóa và IV đã biết. Điều này nhanh hơn elligator2.
Dữ liệu đệm rõ ràng ngẫu nhiên được thêm vào thông điệp 1 và 2. Dữ liệu đệm rõ ràng được bao gồm trong tính toán băm bắt tay (MixHash). Xem các phần KDF bên dưới cho thông điệp 2 và phần 1 thông điệp 3. Dữ liệu đệm AEAD ngẫu nhiên được thêm vào thông điệp 3 và các thông điệp giai đoạn dữ liệu.
Một trường độ dài khung hai byte được thêm vào, như yêu cầu đối với 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 khung AEAD của thông điệp 1 và 2 có độ dài cố định. Khung AEAD của phần 1 thông điệp 3 có độ dài cố định. Độ dài khung AEAD của phần 2 thông điệp 3 được chỉ định trong thông điệp 1.
Trường độ dài khung hai byte được ngụy trang bằng SipHash-2-4, như trong obfs4.
Định dạng tải trọng được định nghĩa 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.
Các nguyên thủy mật mã mới cho I2P
Các triển khai bộ định tuyến I2P hiện tại sẽ yêu cầu triển khai cho các nguyên thủy mật mã tiêu chuẩn sau, không cần thiết cho các giao thức I2P hiện tại:
Tạo khóa và DH X25519
AEAD_ChaCha20_Poly1305 (viết tắt là ChaChaPoly bên dưới)
SipHash-2-4
Ước tính chi phí xử lý
Kích thước thông điệp cho 3 thông điệp:
- 64 byte + đệm (NTCP là 288 byte)
- 64 byte + đệm (NTCP là 304 byte)
- khoảng 64 byte + thông tin bộ định tuyến của Alice + đệm Thông tin bộ định tuyến trung bình khoảng 750 byte Tổng trung bình 814 byte trước khi đệm (NTCP là 448 byte)
- không cần thiết trong NTCP2 (NTCP là 48 byte)
Tổng trước khi đệm: NTCP2: 942 byte NTCP: 1088 byte Lưu ý rằng nếu Alice kết nối với Bob nhằm mục đích gửi Thông điệp Lưu trữ Cơ sở dữ liệu của Thông tin bộ định tuyến cô ấy, thông điệp đó không cần thiết, tiết kiệm khoảng 800 byte.
Các thao tác mật mã sau được yêu cầu bởi mỗi bên để hoàn thành phần 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 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
- DH X25519: 3
- Xác minh chữ ký: 1 (Bob) (Alice đã ký trước khi tạo RI của cô ấy) Có lẽ là Ed25519 (phụ thuộc vào loại chữ ký RI)
Các thao tác mật mã sau đượ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
Thông điệp
Tất cả cá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 các thông điệp Noise, với các sửa đổi để tạo khung và không thể phân biệt. Các triển khai sử dụng các 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/từ định dạng thông điệp Noise. Tất cả các trường được mã hóa đều là văn 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: (Tính năng bảo mật tải trọng)
XK(s, rs): Xác thực Bảo mật
<- s
...
-> e, es 0 2
<- e, ee 2 1
-> s, se 2 5
<- 2 5
Sau khi một phiên đã được thiết lập, Alice và Bob có thể trao đổi các thông điệp Dữ liệu.
Tất cả các loại thông điệp (SessionRequest, SessionCreated, SessionConfirmed, Data và TimeSync) được quy định trong phần này.
Một số ký hiệu:
- RH_A = Băm bộ định tuyến cho Alice (32 byte)
- RH_B = Băm bộ định tuyến cho Bob (32 byte)
Mã hóa được xác thực
Có ba phiên mã hóa được xác thực riêng biệt (CipherStates). Một trong giai đoạn bắt tay, và hai (gửi và nhận) cho giai đoạn dữ liệu. Mỗi cái 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ư sau
+----+----+----+----+----+----+----+----+
| |
+ +
| Dữ liệu được mã hóa và xác thực |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
ChaCha20/Poly1305
Đị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 :: khóa mật mã 32 byte, như được tạo từ KDF
nonce :: Nonce dựa trên bộ đếm, 12 byte.
Bắt đầu từ 0 và tăng dần cho mỗi thông điệp.
Bốn byte đầu tiên luôn bằng 0.
Tám byte cuối là bộ đếm, được mã hóa theo thứ tự nhỏ.
Giá trị tối đa là 2**64 - 2.
Kết nối phải được ngắt và khởi động lại sau khi
đạt đến giá trị đó.
Giá trị 2**64 - 1 không bao giờ được gửi.
ad :: Trong giai đoạn bắt tay:
Dữ liệu liên kết, 32 byte.
Băm SHA256 của tất cả dữ liệu trước đó.
Trong giai đoạn dữ liệu:
Các byte bằng 0
data :: Dữ liệu gốc, 0 hoặc nhiều byte
Đầu ra của hàm mã hóa, đầu vào của hàm giải mã:
+----+----+----+----+----+----+----+----+
|Obfs Len | |
+----+----+ +
| Dữ liệu được mã hóa ChaCha20 |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| Mã xác thực thông điệp Poly1305 |
+ (MAC) +
| 16 byte |
+----+----+----+----+----+----+----+----+
Obfs Len :: Độ dài của (dữ liệu đã mã hóa + MAC) tiếp theo, 16 - 65535
Ngụy trang sử dụng SipHash (xem bên dưới)
Không được sử dụng trong thông điệp 1 hoặc 2, hoặc phần 1 thông điệp 3, nơi độ dài là cố định
Không được sử dụng trong phần 1 thông điệp 3, vì độ dài được chỉ định trong thông điệp 1
dữ liệu đã mã hóa :: Cùng kích thước với dữ liệu gốc, 0 - 65519 byte
MAC :: Mã xác thực thông điệp Poly1305, 16 byte
Đố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 .
Ghi chú
Vì ChaCha20 là một mật mã dòng, nên văn bản gốc không cần được đệm. Các byte dòng khóa bổ sung sẽ bị loại bỏ.
Khóa cho mật mã (256 bit) được thỏa thuận thông qua KDF SHA256. Chi tiết về KDF cho mỗi thông điệp nằm trong các phần riêng biệt bên dưới.
Các khung 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 khung có kích thước thay đổi. Kích thước phần 1 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 khung được thêm vào một trường độ dài hai byte được ngụy trang bằng SipHash như trong obfs4.
Dữ liệu đệm nằm ngoài khung dữ liệu được xác thực cho thông điệp 1 và 2. Dữ liệu đệm được sử dụng trong KDF cho thông điệp tiếp theo để phát hiện sự can thiệp. Bắt đầu từ thông điệp 3, dữ liệu đệm nằm trong khung dữ liệu được xác thực.
Xử lý lỗi AEAD
Trong thông điệp 1, 2 và các phần 1 và 2 của thông điệp 3, kích thước thông điệp AEAD được biết trước. Khi xảy ra lỗi xác thực AEAD, người nhận phải dừng việc xử lý thông điệp tiếp theo và đóng kết nối mà không phản hồi. Điều này nên là một lần đóng bất thường (TCP RST).
Để chống lại việc thăm dò, trong thông điệp 1, sau khi xảy ra lỗi AEAD, Bob nên đặt một khoảng 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) trước khi đóng socket. Bob nên duy trì một danh sách đen các IP có lỗ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” (ngụy trang) bằng SipHash. Cần 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, người nhận nên đặt một khoảng 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, hoặc khi hết thời gian đọc, người nhận nên gửi một tải trọng 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.
Hàm dẫn xuất khóa (KDF) (cho thông điệp bắt tay 1)
KDF tạo ra một khóa mật mã k cho giai đoạn bắt tay 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(), chính xác như được định nghĩa trong thông số kỹ thuật Noise.
Đây là mẫu "e":
// Định nghĩa protocol_name.
Đặt protocol_name = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
(48 byte, mã hóa US-ASCII, không kết thúc NULL).
// Định nghĩa Hash h = 32 byte
h = SHA256(protocol_name);
Định nghĩa ck = khóa nối 32 byte. Sao chép dữ liệu h vào ck.
Đặt ck = h
Định nghĩa rs = khóa tĩnh 32 byte của Bob như được công bố trong RouterInfo
// MixHash(null prologue)
h = SHA256(h);
// cho đến đây, có thể được tính trước bởi Alice cho tất cả các kết nối đi
// Alice phải xác thực rằng khóa tĩnh của Bob là một điểm hợp lệ trên đường cong ở đây.
// Khóa tĩnh Bob
// MixHash(rs)
// || bên dưới có nghĩa là nối
h = SHA256(h || rs);
// cho đến đây, có thể được tính trước bởi Bob cho tất cả các kết nối đến
Đây là mẫu "e":
Alice tạo cặp khóa DH tạm thời e của cô ấy.
// Khóa tạm thời Alice X
// MixHash(e.pubkey)
// || bên dưới có nghĩa là nối
h = SHA256(h || e.pubkey);
// h được sử dụng như dữ liệu liên kết cho AEAD trong thông điệp 1
// Giữ lại Hash h cho KDF thông điệp 2
Kết thúc mẫu "e".
Đây là mẫu "es":
// DH(e, rs) == DH(s, re)
Định nghĩa input_key_material = kết quả DH 32 byte của khóa tạm thời Alice và khóa tĩnh Bob
Đặt input_key_material = kết quả DH X25519
// MixKey(DH())
Định nghĩa temp_key = 32 byte
Định nghĩa HMAC-SHA256(key, data) như trong [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Tạo một khóa tạm thời từ khóa nối và kết quả DH
// ck là khóa nối, được định nghĩa ở trên
temp_key = HMAC-SHA256(ck, input_key_material)
// ghi đè kết quả DH trong bộ nhớ, không còn cần thiết
input_key_material = (tất cả bằng 0)
// Đầu ra 1
// Đặt một khóa nối mới từ khóa tạm thời
// byte() bên dưới có nghĩa là một byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Đầu ra 2
// Tạo khóa mật mã k
Định nghĩa k = 32 byte
// || bên dưới có nghĩa là nối
// byte() bên dưới có nghĩa là một byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// ghi đè temp_key trong bộ nhớ, không còn cần thiết
temp_key = (tất cả bằng 0)
// giữ lại khóa nối ck cho KDF thông điệp 2
Kết thúc mẫu "es".
1) SessionRequest
Alice gửi cho Bob.
Nội dung Noise: Khóa tạm thời X của Alice Tải trọng Noise: Khối tùy chọn 16 byte Tải trọng không phải Noise: Dữ liệu đệm ngẫu nhiên
(Tính năng bảo mật tải trọng)
XK(s, rs): Xác thực Bảo mật
-> e, es 0 2
Xác thực: Không có (0).
Tải trọng này có thể đã được gửi bởi bất kỳ bên nào, bao gồm cả kẻ tấn công chủ động.
Bảo mật: 2.
Mã hóa cho người nhận đã biết, bảo mật chuyển tiếp chỉ cho việc xâm phạm người gửi, dễ bị lặp lại. Tải trọng này được mã hóa dựa trên các DH liên quan đến cặp khóa tĩnh của người nhận. Nếu khóa riêng tĩnh của người nhận bị xâm phạm, ngay cả vào một ngày sau đó, tải trọng này có thể bị giải mã. Thông điệp này cũng có thể bị lặp lại, vì không có đóng góp tạm thời từ người nhận.
"e": Alice tạo một cặp khóa tạm thời mới và lưu trữ nó trong biến e, ghi khóa công khai tạm thời vào bộ đệm thông điệp, và băm khóa công khai cùng với h cũ để suy ra h mới.
"es": Một DH được thực hiện giữa cặp khóa tạm thời của Alice và cặp khóa tĩnh của Bob. Kết quả được băm cùng với ck cũ để suy ra ck mới và k, và n được đặt thành 0.
Giá trị X được mã hóa để đảm bảo tính không thể phân biệt và tính duy nhất của tải trọng, điều này cần thiết để chống lại DPI. Chúng ta 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 cho khóa công khai bộ định tuyến của Bob sẽ quá chậm. Mã hóa AES sử dụng băm bộ định tuyến của Bob làm khóa và IV của Bob như được công bố trong cơ sở dữ liệu mạng.
Mã hóa AES chỉ nhằm mục đích chống DPI. Bất kỳ bên nào biết băm bộ định tuyến của Bob và IV, được công bố trong cơ sở dữ liệu mạng, có thể giải mã giá trị X trong thông điệp này.
Dữ liệu đệm không được Alice mã hóa. Có thể cần Bob giải mã dữ liệu đệm để ngăn chặn các cuộc tấn công dựa trên thời gian.
Nội dung thô:
+----+----+----+----+----+----+----+----+
| |
+ được ngụy trang bằng RH_B +
| Dữ liệu X được mã hóa AES-CBC-256|
+ (32 byte) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| Khung ChaChaPoly |
+ (32 byte) +
| k được định nghĩa trong KDF cho thông điệp 1 |
+ n = 0 |
| xem KDF cho dữ liệu liên kết |
+----+----+----+----+----+----+----+----+
| dữ liệu đệm được xác thực |
~ không được mã hóa (tùy chọn) ~
| độ dài được định nghĩa trong khối tùy chọn |
+----+----+----+----+----+----+----+----+
X :: 32 byte, khóa tạm thời X25519 được mã hóa AES-256-CBC, thứ tự nhỏ
khóa: RH_B
iv: Như được công bố trong mục nhập cơ sở dữ liệu mạng của Bob
đệm :: Dữ liệu ngẫu nhiên, 0 hoặc nhiều byte.
Tổng độ dài thông điệp phải nhỏ hơn hoặc bằng 65535 byte.
Tổng độ dài thông điệp phải nhỏ hơn hoặc bằng 287 byte nếu
Bob đang công bố địa chỉ của mình là NTCP
(xem phần Phát hiện phiên bản bên dưới).
Alice và Bob sẽ sử dụng dữ liệu đệm trong KDF cho thông điệp 2.
Nó được xác thực để bất kỳ sự can thiệp nào cũng sẽ khiến
thông điệp tiếp theo thất bại.
Dữ liệu không được mã hóa (thẻ xác thực Poly1305 không được hiển thị):
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 byte) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| tùy chọn |
+ (16 byte) +
| |
+----+----+----+----+----+----+----+----+
| dữ liệu đệm được xác thực |
+ không được mã hóa (tùy chọn) +
| độ dài được định nghĩa trong khối tùy chọn |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
X :: 32 byte, khóa tạm thời X25519, thứ tự nhỏ
tùy chọn :: khối tùy chọn, 16 byte, xem bên dưới
đệm :: Dữ liệu ngẫu nhiên, 0 hoặc nhiều byte.
Tổng độ dài thông điệp phải nhỏ hơn hoặc bằng 65535 byte.
Tổng độ dài thông điệp phải nhỏ hơn hoặc bằng 287 byte nếu
Bob đang công bố địa chỉ của mình là "NTCP"
(xem phần Phát hiện phiên bản bên dưới)
Alice và Bob sẽ sử dụng dữ liệu đệm trong KDF cho thông điệp 2.
Nó được xác thực để bất kỳ sự can thiệp nào cũng sẽ khiến
thông điệp tiếp theo thất bại.
Khối tùy chọn: Lưu ý: Tất cả các trường đều theo thứ tự lớn.
+----+----+----+----+----+----+----+----+
| id | ver| padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
| tsA | Reserved (0) |
+----+----+----+----+----+----+----+----+
id :: 1 byte, ID mạng (hiện tại là 2, ngoại trừ các mạng thử nghiệm)
Từ 0.9.42. Xem đề xuất 147.
ver :: 1 byte, phiên bản giao thức (hiện tại là 2)
padLen :: 2 byte, độ dài dữ liệu đệm, 0 hoặc nhiều
Hướng dẫn về 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.)
m3p2Len :: 2 byte, độ dài khung AEAD thứ hai trong SessionConfirmed
(phần 2 thông điệp 3) Xem ghi chú bên dưới
Rsvd :: 2 byte, đặt bằng 0 để tương thích với các tùy chọn trong tương lai
tsA :: 4 byte, dấu thời gian Unix, giây không dấu.
Quay vòng vào năm 2106
Reserved :: 4 byte, đặt bằng 0 để tương thích với các tùy chọn trong tương lai
Ghi chú
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ả dữ liệu đệm, nhỏ hơn hoặc bằng 287 byte. Điều này tạo điều kiện nhận diện giao thức tự động bởi Bob. Khi được công bố là “NTCP2”, không có giới hạn kích thước. Xem các phần Địa chỉ được 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 văn bản mã khác nhau cho mỗi phiên.
Bob phải từ chối các kết nối mà giá trị dấu thời gian quá lệch 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ớ cache cục bộ các giá trị bắt tay đã sử dụng trước đó và từ chối các bản sao, để ngăn chặn các cuộc tấn công lặp lại. Các giá trị trong bộ nhớ cache phải có thời gian sống ít nhất 2*D. Các giá trị bộ nhớ cache phụ thuộc vào triển khai, tuy nhiên giá trị X 32 byte (hoặc tương đương đã mã hóa) có thể được sử dụng.
Các khóa tạm thời Diffie-Hellman không bao giờ được sử dụng lại, để ngăn chặn các cuộc tấn công mật mã, và việc sử dụng lại sẽ bị từ chối như một cuộc tấn công lặp lại.
Các tùy chọn “KE” và “auth” phải tương thích, tức là khóa chung K phải có kích thước phù hợp. Nếu thêm các tùy chọn “auth” khác, điều này có thể ngầm thay đổi ý nghĩa của cờ “KE” để sử dụng KDF khác hoặc kích thước rút gọn 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 ở đây.
Dữ liệu đệm 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ó dữ liệu đệm quá mức. Bob sẽ chỉ định các tùy chọn dữ liệu đệm của mình trong thông điệp 2. Hướng dẫn về 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, dấu thời gian, lặp lại rõ ràng hoặc lỗi xác thực khóa, Bob phải dừng việc xử lý thông điệp tiếp theo và đóng kết nối mà không phản hồi. Điều này nên là một lần đóng bất thường (TCP RST). Để chống lại việc thăm dò, sau khi xảy ra lỗi AEAD, Bob nên đặt một khoảng 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), trước khi đóng socket.
Giảm thiểu DoS: DH là một thao tác tương đối tốn kém. Như với giao thức NTCP trước đó, các bộ định tuyến nên thực hiện mọi biện pháp cần thiết để ngăn chặn việc cạn kiệt CPU hoặc kết nối. Đặt giới hạn về số lượng kết nối hoạt động tối đa và số lượng thiết lập kết nối tối đa đang tiến hành. Áp dụng thời gian chờ đọc (cả theo từng lần đọc và tổng cộng 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ì danh sách đen các nguồn thường xuyên thất bại. Không phản hồi khi xảy ra lỗi AEAD.
Để tạo điều kiện nhận diện phiên bản và bắt tay nhanh chóng, các triển khai phải đảm bảo rằng Alice lưu trữ bộ đệm và sau đó gửi 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ả dữ liệu đệm. Điều này làm tăng khả năng dữ liệu sẽ nằm 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 các hộp trung gian), 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 lưu trữ bộ đệm và sau đó gửi toàn bộ nội dung của thông điệp thứ hai cùng một lúc, bao gồm cả dữ liệu đệm. và rằng Bob lưu trữ bộ đệm và sau đó gửi 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 hiệu quả của dữ liệu đệm ngẫu nhiên.
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 thông số tải trọng, cho biết NTCP2. Trường này có thể được sử dụng để chỉ hỗ trợ cho các thay đổi trong tương lai.
Độ dài phần 2 thông điệp 3: Đây là kích thước của khung AEAD thứ hai (bao gồm MAC 16 byte) chứa Thông tin bộ định tuyến của Alice và dữ liệu đệm tùy chọn sẽ được gửi trong thông điệp SessionConfirmed. Vì các bộ định tuyến định kỳ tạo lại và công bố lại Thông tin bộ định tuyến của họ, kích thước của Thông tin bộ định tuyến hiện tại có thể thay đổi trước khi thông điệp 3 được gửi. Các triển khai phải chọn một trong hai chiến lược: a) lưu trữ Thông tin bộ định tuyến hiện tại để gửi trong thông điệp 3, để biết kích thước, và tùy chọn thêm chỗ cho dữ liệu đệm; b) tăng kích thước được chỉ định đủ để cho phép tăng kích thước Thông tin bộ định tuyến, và luôn thêm dữ liệu đệm khi thông điệp 3 thực sự được gửi. Trong cả hai trường hợp, độ dài “m3p2len” được bao gồm trong thông điệp 1 phải chính xác bằng kích thước của khung đó khi được gửi trong thông điệp 3.
Bob phải từ chối kết nối nếu còn dữ liệu đến sau khi xác thực thông điệp 1 và đọc dữ liệu đệm. Không nên có dữ liệu bổ sung từ Alice, vì Bob chưa phản hồi bằng thông điệp 2.
Trường ID mạng được sử dụng để nhanh chóng xác định các kết nối giữa các mạng. Nếu trường này khác 0 và không khớp với ID mạng 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. Từ 0.9.42. Xem đề xuất 147 để biết thêm thông tin.
Hàm dẫn xuất khóa (KDF) (cho thông điệp bắt tay 2 và phần 1 thông điệp 3)
// lấy h được lưu từ KDF thông điệp 1
// MixHash(ciphertext)
h = SHA256(h || tải trọng đã mã hóa 32 byte từ thông điệp 1)
// MixHash(padding)
// Chỉ nếu độ dài dữ liệu đệm khác 0
h = SHA256(h || dữ liệu đệm ngẫu nhiên từ thông điệp 1)
Đây là mẫu "e":
Bob tạo cặp khóa DH tạm thời e của anh ấy.
// h là từ KDF cho thông điệp bắt tay 1
// Khóa tạm thời Bob Y
// MixHash(e.pubkey)
// || bên dưới có nghĩa là nối
h = SHA256(h || e.pubkey);
// h được sử dụng như dữ liệu liên kết cho AEAD trong thông điệp 2
// Giữ lại Hash h cho KDF thông điệp 3
Kết thúc mẫu "e".
Đây là mẫu "ee":
// DH(e, re)
Định nghĩa input_key_material = kết quả DH 32 byte của khóa tạm thời Alice và khóa tạm thời Bob
Đặt input_key_material = kết quả DH X25519
// ghi đè khóa tạm thời Alice trong bộ nhớ, không còn cần thiết
// Alice:
e (công khai và riêng tư) = (tất cả bằng 0)
// Bob:
re = (tất cả bằng 0)
// MixKey(DH())
Định nghĩa temp_key = 32 byte
Định nghĩa HMAC-SHA256(key, data) như trong [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Tạo một khóa tạm thời từ khóa nối và kết quả DH
// ck là khóa nối, từ KDF cho thông điệp bắt tay 1
temp_key = HMAC-SHA256(ck, input_key_material)
// ghi đè kết quả DH trong bộ nhớ, không còn cần thiết
input_key_material = (tất cả bằng 0)
// Đầu ra 1
// Đặt một khóa nối mới từ khóa tạm thời
// byte() bên dưới có nghĩa là một byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Đầu ra 2
// Tạo khóa mật mã k
Định nghĩa k = 32 byte
// || bên dưới có nghĩa là nối
// byte() bên dưới có nghĩa là một byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// ghi đè temp_key trong bộ nhớ, không còn cần thiết
temp_key = (tất cả bằng 0)
// giữ lại khóa nối ck cho KDF thông điệp 3
Kết thúc mẫu "ee".
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: Dữ liệu đệm ngẫu nhiên
(Tính năng bảo mật tải trọng)
XK(s, rs): Xác thực Bảo mật
<- e, ee 2 1
Xác thực: 2.
Xác thực người gửi kháng lại việc mạo danh do xâm phạm khóa (KCI).
Xác thực người gửi dựa trên DH tạm thời-tĩnh ("es" hoặc "se")
giữa cặp khóa tĩnh của người gửi và cặp khóa tạm thời của người nhận.
Giả sử các khóa riêng tương ứng được bảo mật, xác thực này không thể bị làm giả.
Bảo mật: 1.
Mã hóa cho người nhận tạm thời.
Tải trọng này có bảo mật chuyển tiếp, vì mã hóa liên quan đến DH tạm thời-tạm thời ("ee").
Tuy nhiên, người gửi chưa xác thực người nhận,
nên tải trọng này có thể được gửi cho bất kỳ bên nào, bao gồm cả kẻ tấn công chủ động.
"e": Bob tạo một cặp khóa tạm thời mới và lưu trữ nó trong biến e,
ghi khóa công khai tạm thời vào bộ đệm thông điệp,
và băm khóa công khai cùng với h cũ để suy ra h mới.
"ee": Một DH được thực hiện giữa cặp khóa tạm thời của Bob và cặp khóa tạm thời của Alice.
Kết quả được băm cùng với ck cũ để suy ra ck mới và k, và n được đặt thành 0.
Giá trị Y được mã hóa để đảm bảo tính không thể phân biệt và tính duy nhất của tải trọng, điều này cần thiết để chống lại DPI. Chúng ta 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 cho khóa công khai bộ định tuyến của Alice sẽ quá chậm. Mã hóa AES sử dụng băm bộ định tuyến của Bob làm khóa và trạng thái AES từ thông điệp 1 (được khởi tạo bằng IV của Bob như được công bố trong cơ sở dữ liệu mạng).
Mã hóa AES chỉ nhằm mục đích chống DPI. Bất kỳ bên nào biết băm bộ định tuyến của Bob và IV, được công bố trong cơ sở dữ liệu mạng, và đã thu thập 32 byte đầu tiên của thông điệp 1, có thể giải mã giá trị Y trong thông điệp này.
Nội dung thô:
+----+----+----+----+----+----+----+----+
| |
+ được ngụy trang bằng RH_B +
| Dữ liệu Y được mã hóa AES-CBC-256|
+ (32 byte) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| Khung ChaChaPoly |
+ Dữ liệu được mã hóa và xác thực +
| 32 byte |
+ k được định nghĩa trong KDF cho thông điệp 2 |
| n = 0; xem KDF cho dữ liệu liên kết |
+ +
| |
+----+----+----+----+----+----+----+----+
| dữ liệu đệm được xác thực |
+ không được mã hóa (tùy chọn) +
| độ dài được định nghĩa trong khối tùy chọn |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 byte, khóa tạm thời X25519 được mã hóa AES-256-CBC, thứ tự nhỏ
khóa: RH_B
iv: Sử dụng trạng thái AES từ thông điệp 1
Dữ liệu không được mã hóa (thẻ xác thực Poly1305 không được hiển thị):
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 byte) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| tùy chọn |
+ (16 byte) +
| |
+----+----+----+----+----+----+----+----+
| dữ liệu đệm được xác thực |
+ không được mã hóa (tùy chọn) +
| độ dài được định nghĩa trong khối tùy chọn |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 byte, khóa tạm thời X25519, thứ tự nhỏ
tùy chọn :: khối tùy chọn, 16 byte, xem bên dưới
đệm :: Dữ liệu ngẫu nhiên, 0 hoặc nhiều byte.
Tổng độ dài thông điệp phải nhỏ hơn hoặc bằng 65535 byte.
Alice và Bob sẽ sử dụng dữ liệu đệm trong KDF cho phần 1 thông điệp 3.
Nó được xác thực để bất kỳ sự can thiệp nào cũng sẽ khiến
thông điệp tiếp theo thất bại.
Ghi chú
Alice phải xác thực rằng khóa tạm thời của Bob là một điểm hợp lệ trên đường cong ở đây.
Dữ liệu đệm 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ó dữ liệu đệm quá mức. Alice sẽ chỉ định các tùy chọn dữ liệu đệm của mình trong thông điệp 3. Hướng dẫn về 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, dấu thời gian, lặp lại rõ ràng hoặc lỗi xác thực khóa, Alice phải dừng việc xử lý thông điệp tiếp theo và đóng kết nối mà không phản hồi. Điều này nên là một lần đóng bất thường (TCP RST).
Để tạo điều kiện bắt tay nhanh chóng, các triển khai phải đảm bảo rằng Bob lưu trữ bộ đệm và sau đó gửi 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ả dữ liệu đệm. Điều này làm tăng khả năng dữ liệu sẽ nằm 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 các hộp trung gian), và được Alice 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 hiệu quả của dữ liệu đệm ngẫu nhiên.
Alice phải từ chối kết nối nếu còn dữ liệu đến sau khi xác thực thông điệp 2 và đọc dữ liệu đệm. Không nên có dữ liệu bổ sung từ Bob, vì Alice chưa phản hồi bằng thông điệp 3.
Khối tùy chọn: Lưu ý: Tất cả các trường đều theo thứ tự lớn.
+----+----+----+----+----+----+----+----+
| Rsvd(0) | padLen | Reserved (0) |
+----+----+----+----+----+----+----+----+
| tsB | Reserved (0) |
+----+----+----+----+----+----+----+----+
Reserved :: tổng cộng 10 byte, đặt bằng 0 để tương thích với các tùy chọn trong tương lai
padLen :: 2 byte, thứ tự lớn, độ dài dữ liệu đệm, 0 hoặc nhiều
Hướng dẫn về 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.)
tsB :: 4 byte, thứ tự lớn, dấu thời gian Unix, giây không dấu.
Quay vòng vào năm 2106
Ghi chú
- Alice phải từ chối các kết nối mà giá trị dấu thời gian quá lệch so với thời gian hiện tại. Gọi khoảng thời gian tối đa là “D”. Alice phải duy trì một bộ nhớ cache cục bộ các giá trị bắt tay đã sử dụng trước đó và từ chối các bản sao, để ngăn chặn các cuộc tấn công lặp lại. Các giá trị trong bộ nhớ cache phải có thời gian sống ít nhất 2*D. Các giá trị bộ nhớ cache phụ thuộc vào triển khai, tuy nhiên giá trị Y 32 byte (hoặc tương đương đã mã hóa) có thể được sử dụng.
Vấn đề
- Có nên bao gồm các tùy chọn min/max dữ liệu đệm ở đây không?
Mã hóa cho phần 1 thông điệp bắt tay 3, sử dụng KDF thông điệp 2)
// lấy h được lưu từ KDF thông điệp 2
// MixHash(ciphertext)
h = SHA256(h || tải trọng đã mã hóa 24 byte từ thông điệp 2)
// MixHash(padding)
// Chỉ nếu độ dài dữ liệu đệm khác 0
h = SHA256(h || dữ liệu đệm ngẫu nhiên từ thông điệp 2)
// h được sử dụng như dữ liệu liên kết cho AEAD trong phần 1 thông điệp 3, bên dưới
Đây là mẫu "s":
Định nghĩa s = khóa công khai tĩnh của Alice, 32 byte
// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// k là từ thông điệp bắt tay 1
// n là 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || bên dưới có nghĩa là nối
h = SHA256(h || ciphertext);
// h được sử dụng như dữ liệu liên kết cho AEAD trong phần 2 thông điệp 3
Kết thúc mẫu "s".
Hàm dẫn xuất khóa (KDF) (cho phần 2 thông điệp bắt tay 3)
Đây là mẫu "se":
// DH(s, re) == DH(e, rs)
Định nghĩa input_key_material = kết quả DH 32 byte của khóa tĩnh Alice và khóa tạm thời Bob
Đặt input_key_material = kết quả DH X25519
// ghi đè khóa tạm thời Bob trong bộ nhớ, không còn cần thiết
// Alice:
re = (tất cả bằng 0)
// Bob:
e (công khai và riêng tư) = (tất cả bằng 0)
// MixKey(DH())
Định nghĩa temp_key = 32 byte
Định nghĩa HMAC-SHA256(key, data) như trong [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Tạo một khóa tạm thời từ khóa nối và kết quả DH
// ck là khóa nối, từ KDF cho thông điệp bắt tay 1
temp_key = HMAC-SHA256(ck, input_key_material)
// ghi đè kết quả DH trong bộ nhớ, không còn cần thiết
input_key_material = (tất cả bằng 0)
// Đầu ra 1
// Đặt một khóa nối mới từ khóa tạm thời
// byte() bên dưới có nghĩa là một byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Đầu ra 2
// Tạo khóa mật mã k
Định nghĩa k = 32 byte
// || bên dưới có nghĩa là nối
// byte() bên dưới có nghĩa là một byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// h từ phần 1 thông điệp 3 được sử dụng như dữ liệu liên kết cho AEAD trong phần 2 thông điệp 3
// EncryptAndHash(payload)
// EncryptWithAd(h, payload)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// n là 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, payload)
// MixHash(ciphertext)
// || bên dưới có nghĩa là nối
h = SHA256(h || ciphertext);
// giữ lại khóa nối ck cho KDF giai đoạn dữ liệu
// giữ lại hash h cho KDF khóa đối xứng bổ sung (SipHash) giai đoạn dữ liệu
Kết thúc mẫu "se".
// ghi đè temp_key trong bộ nhớ, không còn cần thiết
temp_key = (tất cả bằng 0)
3) SessionConfirmed
Alice gửi cho Bob.
Nội dung Noise: Khóa tĩnh của Alice Tải trọng Noise: Thông tin bộ định tuyến của Alice và dữ liệu đệm ngẫu nhiên Tải trọng không phải Noise: không có
(Tính năng bảo mật tải trọng)
XK(s, rs): Xác thực Bảo mật
-> s, se 2 5
Xác thực: 2.
Xác thực người gửi kháng lại việc mạo danh do xâm phạm khóa (KCI). Xác thực người gửi dựa trên DH tạm thời-tĩnh ("es" hoặc "se") giữa cặp khóa tĩnh của người gửi và cặp khóa tạm thời của người nhận. Giả sử các khóa riêng tương ứng được bảo mật, xác thực này không thể bị làm giả.
Bảo mật: 5.
Mã hóa cho người nhận đã biết, bảo mật chuyển tiếp mạnh. Tải trọng này được mã hóa dựa trên DH tạm thời-tạm thời cũng như DH tạm thời-tĩnh với cặp khóa tĩnh của người nhận. Giả sử các khóa riêng tạm thời được bảo mật, và người nhận không bị mạo danh chủ động bởi kẻ tấn công đã đánh cắp khóa riêng tĩnh của họ, tải trọng này không thể được giải mã.
"s": Alice ghi khóa công khai tĩnh của cô ấy từ biến s vào bộ đệm thông điệp, mã hóa nó, và băm đầu ra cùng với h cũ để suy ra h mới.
"se": Một DH được thực hiện giữa cặp khóa tĩnh của Alice và cặp khóa tạm thời của Bob. Kết quả được băm cùng với ck cũ để suy ra ck mới và k, và n được đặt thành 0.
Điều này chứa hai khung ChaChaPoly. Khung đầu tiên là khóa công khai tĩnh đã mã hóa của Alice. Khung thứ hai là tải trọng Noise: Thông tin bộ định tuyến đã mã hóa của Alice, tùy chọn tùy chọn và dữ liệu đệm tùy chọn. Chúng sử dụng các khóa khác nhau, vì hàm MixKey() được gọi ở giữa.
Nội dung thô:
+----+----+----+----+----+----+----+----+
| |
+ Khung ChaChaPoly (48 byte) +
| Dữ liệu được mã hóa và xác thực |
+ Khóa tĩnh S của Alice +
| (32 byte) |
+ +
| k được định nghĩa trong KDF cho thông điệp 2 |
+ n = 1 |
| xem KDF cho dữ liệu liên kết |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ Độ dài được chỉ định trong thông điệp 1 |
| |
+ Khung ChaChaPoly +
| Dữ liệu được mã hóa và xác thực |
+ +
| Thông tin bộ định tuyến của Alice |
+ sử dụng định dạng khối 2 +
| Tùy chọn của Alice (tùy chọn) |
+ sử dụng định dạng khối 1 |
| Dữ liệu đệm tùy ý |
+ sử dụng định dạng khối 254 |
| |
+ +
| k được định nghĩa trong KDF cho phần 2 thông điệp 3 |
+ n = 0 |
| xem KDF cho dữ liệu liên kết |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 byte, khóa tĩnh X25519 của Alice được mã hóa ChaChaPoly, thứ tự nhỏ
bên trong khung ChaChaPoly 48 byte
Dữ liệu không được mã hóa (các thẻ xác thực Poly1305 không được hiển thị):
+----+----+----+----+----+----+----+----+
| |
+ +
| S |
+ Khóa tĩnh của Alice |
| (32 byte) |
+ +
| |
+ +
+----+----+----+----+----+----+----+----+
| |
+ +
| |
+ +
| Khối Thông tin bộ định tuyến của Alice |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Khối Tùy chọn tùy chọn |
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Khối Dữ liệu đệm tùy chọn |
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 byte, khóa tĩnh X25519 của Alice, thứ tự nhỏ
Ghi chú
Bob phải thực hiện việc xác thực Thông tin bộ định tuyến thông thường. Đảm bảo loại chữ ký được hỗ trợ, xác minh chữ ký, xác minh dấu thời gian trong giới hạn, và bất kỳ kiểm tra nào khác cần thiết.
Bob phải xác minh rằng khóa tĩnh của Alice nhận được trong khung đầu tiên khớp với khóa tĩnh trong Thông tin bộ định tuyến. Bob phải tìm kiếm trước trong Thông tin bộ định tuyến để tìm địa chỉ bộ định tuyến NTCP hoặc NTCP2 có tùy chọn phiên bản (v) khớp. Xem các phần Thông tin bộ định tuyến được công bố và Thông tin bộ định tuyến không được công bố bên dưới.
Nếu Bob có phiên bản cũ hơn của Thông tin bộ định tuyến của Alice trong cơ sở dữ liệu mạng của anh ấy, hãy xác minh rằng khóa tĩnh trong thông tin bộ định tuyến giống nhau trong cả hai, nếu có mặt, và nếu phiên bản cũ hơn nhỏ hơn XXX (xem thời gian xoay khóa 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 ở đây.
Các tùy chọn nên được bao gồm, để chỉ định các tham số dữ liệu đệm.
Khi có bất kỳ lỗi nào, bao gồm AEAD, RI, DH, dấu thời gian hoặc lỗi xác thực khóa, Bob phải dừng việc xử lý thông điệp tiếp theo và đóng kết nối mà không phản hồi. Điều này nên là một lần đóng bất thường (TCP RST).
Để tạo điều kiện bắt tay nhanh chóng, các triển khai phải đảm bảo rằng Alice lưu trữ bộ đệm và sau đó gửi 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ẽ nằm 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 các hộp trung gian), và được Bob 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 hiệu quả của dữ liệu đệm ngẫu nhiên.
Độ dài khung phần 2 thông điệp 3: Độ dài của khung này (bao gồm MAC) được gửi bởi Alice trong thông điệp 1. Xem thông điệp đó để biết các ghi chú quan trọng về việc dành đủ chỗ cho dữ liệu đệm.
Nội dung khung phần 2 thông điệp 3: Định dạng của khung này giống với định dạng các khung giai đoạn dữ liệu, ngoại trừ việc độ dài khung được gửi bởi Alice trong thông điệp 1. Xem bên dưới để biết định dạng khung giai đoạn dữ liệu. Khung phải chứa từ 1 đến 3 khối theo thứ tự sau: 1) Khối Thông tin bộ định tuyến của Alice (bắt buộc) 2) Khối Tùy chọn (tùy chọn) 3) Khối Dữ liệu đệm (tùy chọn) Khung này không bao giờ được chứa bất kỳ loại khối nào khác.
Dữ liệu đệm phần 2 thông điệp 3 không bắt buộc nếu Alice nối một khung giai đoạn dữ liệu (có thể chứa dữ liệu đệm) vào cuối thông điệp 3 và gửi cả hai cùng một lúc, vì nó sẽ xuất hiện như một dòng byte lớn đối với người quan sát. Vì Alice thường, nhưng không phải luôn luôn, có một thông điệp I2NP để gửi cho Bob (đó là lý do cô ấy kết nối với anh ấy), đây là cách triển khai được khuyến nghị, vì hiệu quả và để đảm bảo hiệu quả của dữ liệu đệm ngẫu nhiên.
Tổng độ dài của cả hai khung AEAD thông điệp 3 (phần 1 và 2) là 65535 byte; phần 1