Một mixnet hoạt động hiệu quả, có thể cung cấp mức độ bảo mật ở cấp độ mạng cao hơn Tor, từ lâu đã là giấc mơ của những người ủng hộ quyền riêng tư, các nhà nghiên cứu và cypherpunks. Các mạng mixnet đã xuất hiện trước Tor, và giải pháp triển khai hiệu quả nhất cho đến nay là [Mixminion]https://www.freehaven.net/anonbib/cache/minion-design.pdf, một remailer ‘loại 3’ được sử dụng để gửi email ẩn danh. Kể từ khi việc phát triển mixnet bị đình trệ — với hai nhà phát triển chính của Mixminion, Nick Mathewson và Roger Dingledine, chuyển sang phát triển Tor — đã có rất ít công việc mã nguồn mở được thực hiện kể từ năm 2003, và không có bất kỳ bản cập nhật nào kể từ năm 2011.
Nhờ những nỗ lực bắt đầu từ PANORAMIX và tiếp tục với Nym, các mạng mixnet đã trở lại.
Như đã nêu chi tiết trong [bài đăng trước](https://medium.com/@nymtech/happy-birthday-bitcoin-hello-world-nym-mixnet-600cc7539190 của chúng tôi, mạng mixnet của Nym bao gồm các nút mix-node truyền các gói dữ liệu cho nhau. Các nút này thêm độ trễ thời gian để làm mờ thông tin thời gian của các giao dịch và tạo ra lưu lượng giả khi không có đủ lưu lượng thực. Do đó, mạng mixnet Nym cung cấp mức độ bảo mật cao hơn cho lưu lượng truy cập dựa trên tin nhắn so với Tor hoặc VPN (bao gồm cả dVPN).
Bí quyết thực sự của các mạng mixnet chính là định dạng gói tin Sphinx được cả Nym và [Lightning Network]https://lightning.network/ sử dụng. Sphinx khá khó hiểu và không được Mạng Lightning sử dụng theo cách đảm bảo tính ẩn danh. Vậy hãy cùng tìm hiểu sâu hơn về Sphinx và giải đáp những câu đố của nó!
Sphinx là gì?
[Sphinx]https://www.freehaven.net/anonbib/cache/DBLP:conf/sp/DanezisG09.pdf¹ chuyển tiếp tin nhắn từ người gửi đến người nhận một cách ẩn danh. Nó cung cấp một số tính năng cần thiết để đảm bảo tính ẩn danh của người gửi trong các hệ thống đa bước nhảy:
- Tính không thể liên kết của Bitwise: Bất kỳ gói tin nào đi vào mạng trộn đều không thể được liên kết với bất kỳ gói tin đi ra nào dựa trên biểu diễn nhị phân của nó bởi một kẻ tấn công đang theo dõi mạng. Nói cách khác, các gói dữ liệu này là ẩn danh.
- Tính toàn vẹn: Khả năng chống lại các cuộc tấn công chủ động như tấn công gắn thẻ (tagging) và tấn công tái phát (replay), trong đó kẻ tấn công sửa đổi và chèn lại các tin nhắn để trích xuất thông tin về đích đến hoặc nội dung của chúng.
- Ẩn thông tin định tuyến: Không có nút trộn nào có thể xác định số bước nhảy mà một gói tin đã đi qua cho đến nay, hoặc độ dài đường dẫn của một tin nhắn. Một nút trộn cụ thể chỉ biết đến các nút trộn tiền nhiệm và kế nhiệm của mình.
Với Sphinx, các gói trả lời ẩn danh có thể đảm bảo tính ẩn danh cho người nhận nhờ Khối Trả Lời Sử Dụng Một Lần (SURBs), không thể phân biệt được với các tin nhắn Sphinx được chuyển tiếp trong mạng.
Tóm tắt về Sphinx
Một gói Sphinx bao gồm hai phần độc lập:
- Một header chứa tất cả thông tin cần thiết để định tuyến tin nhắn từ nguồn đến đích; và
- Một payload trong đó nội dung thực tế của tin nhắn được ẩn đi.
Hãy tưởng tượng một thế giới nơi Nakamoto muốn gửi một tin nhắn ẩn danh đến Hal Finney thông qua một mạng trộn, trong đó các nút được biểu thị bằng địa chỉ IP và khóa công khai của chúng. Nakamoto cần phân phối các khóa để mỗi nút trộn (mix-node) trên tuyến đường có thể giải mã thông tin định tuyến cần thiết nhằm chuyển tiếp gói tin được mã hóa, đồng thời vẫn giữ phần còn lại của tuyến đường được ẩn giấu.
Cấu trúc của Sphinx
Đầu tiên, Nakamoto chọn một lộ trình, tra cứu khóa công khai của từng nút trộn và tính toán một khóa chung cho mỗi nút. Thành phần chính của tiêu đề Sphinx là một phần tử nhóm duy nhất ɑ, khi kết hợp với các khóa công khai của các nút, cho phép tính toán một khóa chung cho mỗi nút thông qua trao đổi khóa Diffie-Hellman, nhờ đó nút đầu tiên trong lộ trình do người dùng chọn có thể chuyển tiếp gói tin đến nút tiếp theo, và chỉ nút trộn đó mới có thể giải mã nó.
Khóa chia sẻ tạm thời s này cho phép một nút xử lý gói tin bằng cách suy ra các khóa cần thiết để đảm bảo tiêu đề gói tin không bị sửa đổi thông qua việc kiểm tra thẻ tính toàn vẹn ɣ trong tiêu đề, và giải mã thông tin định tuyến được mã hóa β, chứa một tập hợp các hướng dẫn từ người gửi đến nút trộn được chỉ định về những gì nút trộn nên chuyển tiếp và đến đâu.
Thành phần nhóm ɑ được mã hóa mù tại mỗi bước trộn để ngăn chặn sự tương quan giữa các gói dữ liệu của từng người dùng. Hệ số làm mờ b được trích xuất từ khóa chung s, do đó cả người gửi và một nút trộn tương ứng đều có thể thực hiện tất cả các thao tác cần thiết để chuyển tiếp các gói tin. Dữ liệu δ trong gói tin Sphinx được tính toán bằng thuật toán mã hóa khối rộng để đảm bảo rằng, nếu kẻ tấn công sửa đổi dữ liệu tại bất kỳ điểm nào, nội dung tin nhắn sẽ bị mất vĩnh viễn. Thẻ tính toàn vẹn ɣ được mã hóa trong tiêu đề chỉ cho phép kiểm tra xem tiêu đề gói tin có bị sửa đổi hay không. Tất cả các gói tin đều cần được bổ sung dữ liệu để có cùng độ dài tại mỗi nút trung gian.
Việc đảm bảo tiêu đề duy trì độ dài cố định phức tạp hơn. Sphinx sử dụng kỹ thuật lấp đầy (padding) tinh vi để đảm bảo kích thước gói tin không đổi, từ đó giảm thiểu chi phí phụ trội.
Tạo gói Sphinx
Để định tuyến tin nhắn m qua một đường dẫn được chọn gồm các nút trộn M₀, M₁, M₂, Nakamoto tạo ra một giá trị bí mật mới x và tính toán trước tất cả các phần tử nhóm ɑ, khóa chia sẻ s và các yếu tố che giấu b bằng cách sử dụng x và các khóa công khai của các nút trộn. Anh bắt đầu quá trình mã hóa tiêu đề bằng cách đóng gói theo lớp thông tin định tuyến như địa chỉ IP cùng với thẻ tính toàn vẹn tiêu đề cho từng nút trộn (mix-node) trong lộ trình, từ nút cuối cùng đến nút đầu tiên.
Lớp trong cùng được xây dựng dưới dạng sự nối tiếp của địa chỉ ∆* của Finney, một định danh I được sử dụng cho SURBs, và chuỗi padding, nhằm đảm bảo độ dài đường dẫn không bị tiết lộ một cách vô tình. Sau đó, các dữ liệu này được mã hóa bằng phép XOR với đầu ra của bộ tạo số ngẫu nhiên giả được khởi tạo bằng khóa chung _s_₂. Kết quả cuối cùng được hợp nhất với một chuỗi lấp đầy ɸ, việc thêm chuỗi này đảm bảo các gói tiêu đề giữ nguyên kích thước khi các lớp mã hóa được thêm vào hoặc loại bỏ. Khi thông tin định tuyến được mã hóa cuối cùng β₂ đã sẵn sàng, Nakamoto tính toán HMAC của nó làm thẻ toàn vẹn ɣ₂ = HMAC(_s_₂, β₂) và mã hóa thông tin định tuyến β này được nối với kiểm tra toàn vẹn ɣ. Quá trình bắt đầu lại từ β₁, sau đó chuyển sang β tiếp theo theo cách đệ quy, như minh họa dưới đây:
Xây dựng gói tin Sphinx: Màu xám càng đậm, mức độ mã hóa càng cao!
Sau đó, Nakamoto tái sử dụng các khóa chia sẻ đã tính toán để mã hóa theo lớp dữ liệu tải. Cũng giống như trong tiêu đề, việc đóng gói dữ liệu được thực hiện theo thứ tự ngược lại so với lộ trình đi qua các nút trộn. Giá trị ban đầu δ_₂_ được tạo ra bằng thuật toán mã hóa khối rộng, sử dụng khóa s₂, từ chuỗi ghép nối của tin nhắn m, địa chỉ Finney ∆ và một chuỗi ký tự lấp đầy bằng byte 0, cho phép xác minh rằng nội dung tin nhắn không bị thay đổi trong quá trình truyền tải — nếu một bit duy nhất bị kẻ tấn công thay đổi, thuật toán mã hóa khối rộng sẽ giải mã tải trọng thành các bit ngẫu nhiên.
Finney vẫn cần có khả năng phân biệt liệu đó là một thông điệp hợp lệ hay một văn bản mã hóa ngẫu nhiên bằng cách sử dụng phần lấp đầy bằng các byte 0 theo trình tự đã biết bổ sung. Khi δ_₂_ đã sẵn sàng, Nakamoto lại mã hóa nó bằng s₁ và s₀, lần lượt từng cái một.
Đang xử lý gói dữ liệu Sphinx
- Khi nhận được một gói dữ liệu, nút mixnet sẽ trích xuất phần tử nhóm ɑ từ tiêu đề và kết hợp nó với khóa bí mật của chính mình để suy ra khóa chung s
- Sử dụng s, thuật toán trộn tính toán hàm băm có khóa (keyed-hash) của thông tin định tuyến đã được mã hóa dưới dạng HMAC(s, β) và so sánh với thẻ tính toàn vẹn ɣ được đính kèm trong tiêu đề gói tin. Nếu kiểm tra tính toàn vẹn thất bại do tiêu đề đã bị can thiệp, gói tin sẽ bị loại bỏ. Nếu không, nút trộn sẽ chuyển sang bước 3.
- Nút mixnet hiện đã sẵn sàng để giải mã tệp đính kèm β. Để trích xuất các hướng dẫn định tuyến, nút mixnet trước tiên sẽ thêm một đoạn đệm 0 byte vào cuối β và giải mã khối thông tin định tuyến B đã được đệm bằng cách thực hiện phép XOR với một luồng byte ngẫu nhiên giả được tạo ra bằng s. Số lượng padding 0 byte được thêm vào β bằng với độ dài của các hướng dẫn định tuyến mà nút mixnet cần trích xuất để duy trì tính bất biến về độ dài. Lưu ý rằng vì phần padding được băm trong thẻ toàn vẹn ɣ, nên nó phải giống hệt với phần padding được Nakamoto tạo sẵn.
- Nút trộn (mix-node) phân tích các hướng dẫn định tuyến từ B để lấy địa chỉ của nút trộn tiếp theo (hoặc trong trường hợp bước nhảy cuối cùng, địa chỉ đích ∆ và mã định danh I), cũng như các thẻ toàn vẹn mới ɣ’ và β’, vốn cần được chuyển tiếp đến bước nhảy tiếp theo.
- Nút mixnet cũng thực hiện giải mã thuật toán mã hóa khối rộng của δ, tạo ra δ’, sau đó sẽ được chuyển tiếp đến nút tiếp theo.
- Nút mixnet làm mờ giá trị ɑ nhận được bằng cách sử dụng hệ số làm mờ được dẫn xuất từ khóa chung s để thu được một phần tử nhóm mới ɑ’.
Khi cả tiêu đề và dữ liệu đều đã được mã hóa, và phần tử nhóm đã được che giấu, nút trộn có thể tạo ra một gói tin mới dưới dạng ((ɑ’, β’, ɣ’), δ’) và chuyển tiếp nó đến địa chỉ tiếp theo.
Hình minh họa gốc về định dạng gói tin Sphinx, trích từ Danezis và Goldberg (2014)
Cách Nym chống lại các cuộc tấn công vào Sphinx
Một trong những điểm nổi bật nhất của Sphinx là tính bảo mật có thể chứng minh được — bài báo gốc cung cấp bằng chứng bảo mật cho các thuộc tính mà nó giả định. Nói chung, chúng tôi muốn có các bằng chứng bảo mật, điều mà các nhà mật mã học thường thực hiện thủ công để chứng minh rằng một thiết kế thực sự sở hữu một tập hợp các tính chất có thể được chứng minh logic từ một tập hợp các giả định toán học. Việc chứng minh các thuộc tính bảo mật riêng tư khó khăn hơn nhiều, thường đòi hỏi phải thực hiện mô phỏng.
Khi các nhà mật mã học thực hiện các bằng chứng bảo mật bằng tay, họ có thể mắc lỗi hoặc đơn giản là bỏ sót một số khía cạnh của những gì họ muốn chứng minh. Công trình của Kuhn và cộng sự,² cho thấy rằng do các thuộc tính hình thức được Camenisch và Lysyanskaya³ định nghĩa cho các hệ thống dựa trên định tuyến onion là không đầy đủ, nên một lỗ hổng đáng kể trong thiết kế ban đầu của gói tin Sphinx đã không được phát hiện trong bằng chứng bảo mật do Danezis và Goldberg trình bày. Nếu lỗ hổng này không được khắc phục, nó có thể gây tổn hại đáng kể đến quyền riêng tư của người dùng trong các hệ thống sử dụng Sphinx.
Thiết kế ban đầu của Sphinx đề xuất sử dụng padding 0 byte, nhưng chỉ với một chuỗi các số 0, vì padding này cho phép nút trộn cuối cùng trong đường dẫn suy ra thông tin về độ dài của đường dẫn, do đó phá vỡ một trong những thuộc tính bảo mật mà Sphinx hứa hẹn, và có thể suy ra thông tin quan trọng về lộ trình hoặc thậm chí là điểm đến cuối cùng.
Như đã mô tả trước đó, nút mix cuối cùng trong tuyến đường nhận được lớp thông tin định tuyến được mã hóa sâu nhất β, được tạo ra bằng cách mã hóa địa chỉ người nhận (∆), một mã định danh (I) và một phần đệm 0 byte, đồng thời kết hợp với chuỗi lấp đầy ɸ.
Theo ký hiệu được sử dụng trong bài báo Sphinx, β bên trong nhất được tạo ra như
trong đó |ɸ| = 2(v-1)κ, và κ, r lần lượt là tham số bảo mật và độ dài đường dẫn tối đa, trong khi v là độ dài đường dẫn mà gói tin đi qua. Quá trình xử lý β nhận được bởi nút mixnet được thực hiện như sau
Vậy, làm thế nào mà nút trộn cuối cùng có thể suy ra bất kỳ thông tin nào về độ dài đường đi từ phép toán kỳ diệu này?
Để giải thích cách thức hoạt động của cuộc tấn công này, chúng tôi đưa ra một ví dụ đơn giản. Trước tiên, hãy nhớ rằng với giá trị x = a⊕b, cả x, a và b đều có cùng độ dài, và nếu chúng ta thực hiện phép XOR giữa x và b, chúng ta sẽ nhận được x⊕b = a⊕b⊕b = a. Ví dụ, giả sử rằng đầu ra của PRNG với khóa chung của nút v-1 làm đầu vào là 10101010101010101010….
Bây giờ chúng ta hãy xem xét giá trị β sau đây nhận được từ lần trộn cuối cùng
Bây giờ, theo bước (2), chúng ta thực hiện các thao tác tương tự như nút trộn đầu ra sẽ thực hiện để giải mã và phân tích β
Theo thiết kế, nút trộn cuối cùng trong đường dẫn biết tổng độ dài của β dự kiến (trong ví dụ của chúng tôi là 9 bit), và rằng chuỗi ghép nối giữa địa chỉ đích (∆) và mã định danh (I) được tiếp nối lần lượt bởi các bit lấp đầy bằng 0 và các bit ngẫu nhiên giả của chuỗi lấp đầy. Với kiến thức về độ dài chính xác của ∆ và I, nút trộn cuối cùng trung thực nhưng tò mò sẽ tìm kiếm vị trí của bit 1 đầu tiên sau mã định danh, vì nó biết rằng chuỗi lấp đầy bắt đầu từ đó hoặc sớm hơn. Quan sát cho thấy bit đầu tiên sau mã định danh cho phép lần trộn cuối cùng xác định giới hạn dưới của độ dài chuỗi lấp đầy. Vì tổng độ dài của ɸ được định nghĩa theo thiết kế là gấp đôi độ dài lộ trình nhân với tham số bảo mật κ, nên giới hạn dưới của độ dài chuỗi lấp đầy sẽ tiết lộ thông tin về giới hạn dưới của độ dài đường dẫn được sử dụng.
Tại sao việc biết độ dài của đường đi lại có hại
Như các nghiên cứu đã chỉ ra,⁴ trong các mạng sử dụng cấu trúc hạn chế hoặc thưa thớt (ví dụ như Lightning), việc biết được độ dài đường dẫn sẽ làm giảm tập ẩn danh mà người gửi có thể ẩn mình dưới đó. Ví dụ trong hình dưới đây cho thấy việc biết giới hạn dưới của độ dài đường dẫn có thể làm giảm mức độ ẩn danh của người gửi như thế nào. Nếu D đóng vai trò là nút trộn đầu ra và chuyển tiếp một gói tin đến Timmy, mà không biết độ dài của đường dẫn, thì bất kỳ nút nào trong số A, B, C, E, G, F đều có thể là người gửi. Tuy nhiên, nếu D có thể suy ra rằng độ dài đường đi ít nhất là 3, thì bằng cách xem xét đồ thị mạng, chúng ta có thể suy ra rằng chỉ có A hoặc B mới có thể là người gửi, do đó tập hợp các người gửi tiềm năng sẽ giảm đi đáng kể.
Việc ngăn chặn cuộc tấn công này khá đơn giản. Trong (1), khi tạo β thay vì sử dụng phương pháp lấp đầy bằng số 0, chúng ta chỉ cần sử dụng phương pháp lấp đầy bằng các bit ngẫu nhiên. Thực ra, bản triển khai bằng Python của George Danezis đã nhận ra [lỗ hổng](https://github.com/lightningnetwork/lightning-onion/issues/42 này.
Hình 1
Tuy nhiên, cuộc tấn công này không ảnh hưởng đến Nym
- Nym sử dụng cấu trúc phân tầng nhằm tối đa hóa tính ẩn danh, do đó tất cả các đường dẫn đều có độ dài bằng nhau và mỗi nút trộn đều biết vị trí của mình trong đường dẫn. Điều này không đúng với Lightning. Nó sử dụng các đường dẫn có độ dài thay đổi nên phiên bản Sphinx ban đầu của nó dễ bị tấn công này, mặc dù hiện tại lỗi này đã được [sửa chữa]https://github.com/lightningnetwork/lightning-onion/issues/42.
- Lớp mã hóa cuối cùng của Sphinx được loại bỏ bởi chính ứng dụng, chứ không phải bởi nút thoát (như trong Tor). Tuy nhiên, [viên bản triển khai Sphinx bằng Rust](https://github.com/nymtech/sphinx của Nym có khả năng chống lại cuộc tấn công này (nó sử dụng padding ngẫu nhiên) và do đó có thể được tái sử dụng một cách an toàn bởi bất kỳ thiết kế nào dựa trên Sphinx.
Điều gì tiếp theo cho Nym?
Gói Sphinx ẩn danh đầu tiên của Nym sẽ không phải là gói cuối cùng. Mạng Nym sẽ dần phát triển thành một mixnet ổn định, đa năng dành cho bất kỳ ứng dụng internet nào. Mạng thử nghiệm của chúng tôi đã đi vào hoạt động và dự kiến sẽ chính thức ra mắt vào cuối năm 2020.
Nhưng rốt cuộc thì ai cần quyền riêng tư ở cấp độ mạng chứ? Hóa ra là hầu như tất cả mọi người.
Mạng Lightning hiện đã sử dụng các gói tin Sphinx, nhưng theo cách làm suy yếu khả năng bảo mật giao dịch của nó, như Claudia Diaz đã trình bày tại Hội nghị Lightning vào tháng 11 năm 2019. Với một số thay đổi, Lightning có thể được cải thiện về mặt bảo mật, vì nó đã chia sẻ nhiều cơ sở hạ tầng như Sphinx với Nym. Sự kết hợp giữa Nym và Lightning có thể là con đường khả thi nhất để đảm bảo tính riêng tư cho Bitcoin.
(iframe src="https://www.youtube.com/embed/g55kMhggIBY?feature=oembed" width="700" height="393")(/iframe)
Claudia Diaz trình bày về lý do tại sao Sphinx không hỗ trợ tính riêng tư của Lightning — và cách khắc phục vấn đề này.
Các loại tiền điện tử được tăng cường quyền riêng tư và các chuỗi phụ (side-chains) của bất kỳ loại tiền điện tử nào cũng nên sử dụng tính ẩn danh ở cấp độ mạng; nếu không, các cuộc tấn công có thể tận dụng dữ liệu thời gian để loại bỏ tính ẩn danh của các gói tin và thậm chí dẫn đến các cuộc tấn công vào các kỹ thuật bảo mật trên chuỗi như zkSNARKS. Chúng tôi đang tiến hành các hoạt động tiếp cận với nhiều cộng đồng, và sẽ có thêm thông tin trong thời gian tới.
Và đừng quên sự quan tâm dành cho VPN phi tập trung từ Brave và các bên khác. Tốc độ truyền gói tin của Sphinx có thể đạt mức nào? Sphinx sử dụng nhiều thuật toán mã hóa bất đối xứng và các thuật toán mã hóa khối rộng độc đáo để đạt được tính không liên kết, nhưng có lẽ nó cũng có thể được thiết kế lại để đạt được tốc độ cần thiết, từ đó biến các trường hợp sử dụng này thành hiện thực.
Sphinx mang đến khả năng ẩn danh cho các gói dữ liệu internet thông thường — nhưng quyền lực lớn đi kèm với trách nhiệm lớn. Chúng tôi rất mong chờ được chứng kiến những loại dịch vụ và ứng dụng mới nào sẽ đảm nhận trách nhiệm này và phát triển dựa trên nền tảng Nym!