Tôi đã triển khai trao đổi khóa bất đối xứng để tạo khóa đối xứng.
Câu hỏi của tôi mang tính triết học/pháp lý nhiều hơn về trách nhiệm trao đổi khóa và điều gì xảy ra khi giả sử, một khóa thường được biết đến được sử dụng.
Tôi muốn đặt các biến cơ sở này:
- Máy khách có khóa công khai của máy chủ được mã hóa cứng trong bộ nhớ
- Máy chủ có khóa riêng được mã hóa cứng trong bộ nhớ
- Có một mã hóa cứng
nonce_size
- Có một mã hóa cứng
public_key_size
- Có một mã hóa cứng
mac_size
Các bước giao tiếp để trao đổi như sau:
- Sau khi kết nối TCP thành công, máy khách tạo khóa công khai mới
client_pubkey
, mã hóa khóa công khai của chính nó client_pubkey
sử dụng một nonce mới temp_nonce_1
và mã hóa cứng server_pubkey
và gửi một thông báo trong đó các byte đầu tiên là nonce và phần còn lại là mã hóa client_pubkey
(bao gồm cả mac của nó). Cái này có kích thước đã biết là nonce_size + public_key_size + mac_size
.
- Máy chủ nhận được một tin nhắn, kiểm tra kích thước của nó cho chính xác
nonce_size + public_key_size + mac_size
. Nếu đúng như vậy, nó cho rằng đó là một trao đổi khóa. Nó giải mã public_key. Sau đó, máy chủ sẽ tạo một tệp mới symmetric_key
và gửi lại một tin nhắn có chứa một nonce mới tmp_nonce2
và khóa đối xứng + mac được mã hóa bằng mã nhận được client_pubkey
.
- Máy khách nhận được thông báo này, biết chính xác kích thước của nó nếu không nó sẽ từ chối. Khách hàng bây giờ có một khóa đối xứng để sử dụng.
- Máy chủ và máy khách giao tiếp thông qua các phím đối xứng.
Vì vậy, đây là nỗ lực của tôi để hiểu tại sao điều này là an toàn:
- Trong trường hợp các byte rác ngẫu nhiên được gửi đến máy chủ, máy chủ sẽ tạo một khóa, mã hóa khóa bằng cách sử dụng rác, tạo ra nhiều rác hơn rồi gửi đi. Vì vậy, trong thực tế, chúng tôi đã gửi nhiều rác hơn và sau đó chúng tôi không bao giờ nhận được một tin nhắn hợp lệ và cuối cùng là hết thời gian chờ, đóng kết nối. Tác hại duy nhất ở đây là lãng phí thời gian của CPU trong vài giây.
- Máy khách gửi cụ thể một public_key chỉ bằng 0 (hoặc một số bitset rõ ràng khác, như tất cả 1) và một nonce hợp lệ (hoặc cũng bằng 0). Trong trường hợp đó, máy chủ coi số 0 là khóa chung và gửi một khóa đối xứng được mã hóa thông qua khóa công khai. Tuy nhiên, điều này vẫn an toàn vì có khóa công khai bằng 0 giả định rằng bạn biết khóa riêng cho biết khóa public_key được lấy từ đâu, có thể mất hàng tỷ năm để thiết kế ngược, vì vậy nó vẫn an toàn.
- Giả sử máy khách và máy chủ có thể khởi động lại quá trình này vô hạn (và không có giới hạn x-try trên máy chủ), giả sử bằng cách nào đó nhờ may mắn khôn lường và gửi các byte ngẫu nhiên, một trao đổi khóa xảy ra và một thông báo hợp lệ về bất kỳ dữ liệu nào mà máy chủ đã mong đợi được gửi và phân tích cú pháp bởi máy chủ, chúng tôi giơ tay lên trời vì nó gần như không thể tiếp cận được và về cơ bản
điều tồi tệ xảy ra
.
- Trong trường hợp này, chúng tôi không thể nói ai phải chịu trách nhiệm phải không? Máy chủ không thể làm gì khi biết đó là một gói độc hại.
- Ngay cả khi chúng tôi có giới hạn thử lại x là 2 lần, thì về mặt lý thuyết, điều đó thậm chí có thể xảy ra trên kết nối đầu tiên từ một địa chỉ IP và một lần nữa, chúng tôi không thể làm gì về điều đó.
Vì vậy, về cơ bản, mọi thứ đều an toàn vì cơ sở của tin nhắn đầu tiên dự kiến sẽ được mã hóa bằng public_key mà chỉ máy chủ mới biết private_key phù hợp, phải không? Và rằng trong trường hợp tuyệt đối rằng một cái gì đó, bằng cách nào đó, đã từng xoay sở để vượt qua, thì kết quả sẽ bị ném vào cái không xác định?
Tôi xin lỗi nếu điều này thực sự ngắn gọn, tôi chỉ đang cố gắng xác minh cả sự hiểu biết của mình về lý thuyết và đảm bảo không có sai sót trong việc thực hiện một giao thức như vậy.