1. Thực hiện mã hóa và giải mã thử nghiệm với Kyber qua OpenSSL
Bước đầu tiên là xác minh khả năng thực thi của thuật toán Kyber (còn gọi là CRYSTALS-Kyber) trong môi trường OpenSSL đã được tích hợp module mã hóa Post-Quantum.
Chúng ta sẽ sử dụng công cụ openssl pkey để tạo cặp khóa, sau đó dùng openssl pkeyutl để thực hiện mã hóa (Encapsulation) và giải mã (Decapsulation). Lưu ý: Kyber hoạt động theo cơ chế mã hóa khóa công khai (KEM - Key Encapsulation Mechanism), không phải mã hóa dữ liệu trực tiếp.
Trước tiên, tạo một cặp khóa Kyber512 (mức an toàn cơ bản nhất tương đương AES-128) để làm mẫu thử.
openssl genpkey -algorithm KYBER512 -out kyber512_private.pem -pkeyopt digest:sha256
Kết quả mong đợi: File kyber512_private.pem được tạo ra, chứa cả khóa riêng (private key) và khóa công khai (public key) định dạng PKCS#8.
Tiếp theo, trích xuất khóa công khai từ file vừa tạo để dùng cho quá trình mã hóa.
openssl pkey -in kyber512_private.pem -pubout -out kyber512_public.pem
Kết quả mong đợi: File kyber512_public.pem được tạo, chứa chỉ khóa công khai, sẵn sàng gửi cho bên nhận.
Giả lập kịch bản mã hóa: Tạo một secret key ngẫu nhiên (shared secret) và mã hóa nó bằng khóa công khai. Trong thực tế, shared secret này sẽ được dùng để khởi tạo session key cho giao thức TLS.
openssl pkeyutl -encrypt -pubin -inkey kyber512_public.pem -in /dev/urandom -pkeyopt digest:sha256 -out kyber_ciphertext.bin -pkeyopt keylen:32
Chú ý: Cú pháp trên giả định OpenSSL đã hỗ trợ đầy đủ tham số -pkeyopt keylen cho Kyber. Nếu hệ thống bạn chạy OpenSSL phiên bản cũ chưa hỗ trợ đầy đủ KEM, bạn có thể cần dùng lệnh openssl enc với một secret key giả định hoặc sử dụng thư viện liboqs wrapper. Ở đây ta giả định OpenSSL 3.2+ hoặc bản fork đã tích hợp Kyber vào kernel space.
Thực hiện giải mã (Decapsulation) để khôi phục lại shared secret từ ciphertext và khóa riêng.
openssl pkeyutl -decrypt -inkey kyber512_private.pem -in kyber_ciphertext.bin -out kyber_decrypted_secret.bin -pkeyopt digest:sha256
Kết quả mong đợi: File kyber_decrypted_secret.bin được tạo. Nội dung của file này phải trùng khớp hoàn toàn với secret key đã được tạo ra trong bước mã hóa.
Verify kết quả: So sánh checksum của shared secret gốc (nếu có) hoặc kiểm tra độ dài file đầu ra.
ls -l kyber_decrypted_secret.bin && xxd kyber_decrypted_secret.bin
Kết quả: File có kích thước 32 bytes (tương ứng với SHA256 digest size đã cấu hình), nội dung hex ngẫu nhiên.
2. Đo lường thời gian thực thi và tiêu thụ tài nguyên CPU/RAM
Sau khi xác minh tính đúng đắn của thuật toán, bước tiếp theo là đo lường hiệu năng thực tế trên phần cứng Linux của bạn. Chúng ta sẽ tập trung vào 3 chỉ số: Thời gian tạo khóa (KeyGen), Thời gian mã hóa (Encap), và Thời gian giải mã (Decap).
Sử dụng lệnh time để đo thời gian thực thi CPU và thời gian thực (wall clock). Chạy thử nghiệm với thuật toán Kyber768 (mức an toàn cao hơn, tương đương AES-256) để có dữ liệu so sánh rõ ràng.
Đo thời gian tạo khóa Kyber768.
time for i in {1..100}; do openssl genpkey -algorithm KYBER768 -out /dev/null -pkeyopt digest:sha384; done
Kết quả mong đợi: Hiển thị tổng thời gian thực hiện 100 lần tạo khóa. Bạn cần chia tổng thời gian cho 100 để ra thời gian trung bình cho 1 lần tạo khóa. Giá trị thường nằm trong khoảng 0.1ms - 0.5ms tùy CPU.
Đo thời gian mã hóa (Encapsulation) và giải mã (Decapsulation). Ta cần tạo sẵn 100 cặp khóa và ciphertext để đo tốc độ xử lý hàng loạt.
Tạo script shell đơn giản để chạy benchmark toàn diện.
cat > /tmp/kyber_bench.sh /dev/null
openssl pkey -in $KEY_FILE -pubout -out $PUB_FILE > /dev/null
done
# 2. Encapsulation Benchmark
echo "Step 2: Encapsulation ($COUNT iterations)"
# Reuse the last generated key for speed
time for i in $(seq 1 $COUNT); do
openssl pkeyutl -encrypt -pubin -inkey $PUB_FILE -in /dev/urandom -pkeyopt digest:sha384 -out $CT_FILE -pkeyopt keylen:32 > /dev/null
done
# 3. Decapsulation Benchmark
echo "Step 3: Decapsulation ($COUNT iterations)"
time for i in $(seq 1 $COUNT); do
openssl pkeyutl -decrypt -inkey $KEY_FILE -in $CT_FILE -out $SECRET_FILE -pkeyopt digest:sha384 > /dev/null
done
echo "=== Done ==="
EOF
chmod +x /tmp/kyber_bench.sh
Chạy script benchmark.
bash /tmp/kyber_bench.sh
Kết quả mong đợi: Đầu ra hiển thị 3 phần thời gian (User, System, Real) cho từng bước. Lưu ý giá trị "User time" để đánh giá hiệu năng CPU thuần túy.
Đo lường tiêu thụ RAM trong quá trình chạy. Sử dụng /proc/[pid]/statm hoặc công cụ smem nếu đã cài đặt. Ở đây ta dùng cách đơn giản hơn: chạy valgrind với chế độ --tool=massif (nếu cần chi tiết) hoặc đơn giản là quan sát top trong khi chạy.
Để đo peak memory, ta dùng time với tùy chọn -v (posix time) để xem "Maximum resident set size".
time -v openssl genpkey -algorithm KYBER1024 -out /dev/null -pkeyopt digest:sha512
Kết quả mong đợi: Dòng "Maximum resident set size" cho biết lượng RAM tối đa (KB) mà OpenSSL sử dụng cho một lần tạo khóa Kyber1024. Kyber1024 sẽ tốn RAM nhiều hơn Kyber512.
Verify kết quả: Ghi nhận lại các chỉ số (ms/lần, MB RAM) vào file log để so sánh ở phần tiếp theo.
echo "Kyber768 KeyGen: $(grep "Step 1" -A 5 /tmp/kyber_bench.log | grep "real" | awk '{print $2}')" > /tmp/perf_results.txt
3. So sánh kết quả hiệu năng giữa Kyber và các thuật toán truyền thống
Để đánh giá tác động của Post-Quantum, chúng ta cần so sánh trực tiếp Kyber với thuật toán truyền thống đang dùng phổ biến nhất trong TLS hiện nay: ECDH (Elliptic Curve Diffie-Hellmen) với đường cong P-256 (secp256r1) hoặc X25519.
Thực hiện benchmark tương tự như phần 2 nhưng với thuật toán X25519.
time for i in {1..1000}; do openssl genpkey -algorithm X25519 -out /dev/null; done
Kết quả mong đợi: Thời gian tạo khóa X25519 thường nhanh hơn Kyber512 đáng kể (khoảng 5-10 lần), nhưng chậm hơn Kyber1024.
So sánh kích thước khóa và ciphertext. Đây là yếu tố quan trọng ảnh hưởng đến băng thông mạng.
Đo kích thước file khóa công khai và ciphertext của Kyber512, Kyber768, Kyber1024 và X25519.
openssl genpkey -algorithm KYBER512 -out /tmp/k512.pem && openssl pkey -in /tmp/k512.pem -pubout -out /tmp/k512_pub.pem
openssl genpkey -algorithm KYBER768 -out /tmp/k768.pem && openssl pkey -in /tmp/k768.pem -pubout -out /tmp/k768_pub.pem
openssl genpkey -algorithm KYBER1024 -out /tmp/k1024.pem && openssl pkey -in /tmp/k1024.pem -pubout -out /tmp/k1024_pub.pem
openssl genpkey -algorithm X25519 -out /tmp/x25519.pem && openssl pkey -in /tmp/x25519.pem -pubout -out /tmp/x25519_pub.pem
ls -l /tmp/*_pub.pem | awk '{print $9, $5}'
Kết quả mong đợi:
- X25519 Public Key: 32 bytes
- Kyber512 Public Key: ~800 bytes
- Kyber768 Public Key: ~1100 bytes
- Kyber1024 Public Key: ~1500 bytes
Điều này chứng tỏ overhead về kích thước gói tin của Kyber lớn hơn đáng kể so với Elliptic Curve.
Đo kích thước Ciphertext (bản mã). Ciphertext của Kyber sẽ dài hơn nhiều so với ECDH shared secret.
# Tạo ciphertext mẫu cho từng loại và đo kích thước
openssl pkeyutl -encrypt -pubin -inkey /tmp/k512_pub.pem -in /dev/urandom -pkeyopt digest:sha256 -out /tmp/ct512.bin -pkeyopt keylen:32
openssl pkeyutl -encrypt -pubin -inkey /tmp/k768_pub.pem -in /dev/urandom -pkeyopt digest:sha384 -out /tmp/ct768.bin -pkeyopt keylen:32
openssl pkeyutl -encrypt -pubin -inkey /tmp/x25519_pub.pem -in /dev/urandom -out /tmp/ctx25519.bin # X25519 thường dùng ECDH, đây là mô phỏng
ls -l /tmp/ct*.bin | awk '{print $9, $5}'
Kết quả mong đợi:
- Kyber512 Ciphertext: ~768 bytes
- Kyber768 Ciphertext: ~1024 bytes
- X25519 (Shared Secret): 32 bytes (Lưu ý: ECDH không tạo ciphertext, nó trao đổi public key để tính shared secret. Ở đây ta so sánh overhead của Kyber là sự kết hợp giữa Public Key + Ciphertext).
Tổng hợp bảng so sánh (dùng lệnh để tạo file văn bản).
cat > /tmp/perf_comparison.txt
Verify kết quả: Kiểm tra xem các giá trị đo được từ bước 2 có khớp với xu hướng trong bảng này không. Nếu thời gian thực tế chậm hơn nhiều, có thể do CPU không hỗ trợ lệnh vector (AVX2) hoặc hệ thống đang bị quá tải.
4. Kiểm tra tính tương thích của Kyber với các ứng dụng network hiện có
Điểm mấu chốt của việc triển khai Post-Quantum là khả năng tích hợp vào hạ tầng mạng hiện hữu (TLS, SSH, IPsec). Chúng ta sẽ kiểm tra khả năng dùng Kyber trong handshake của TLS 1.3 và SSH.
Kiểm tra hỗ trợ Kyber trong OpenSSL S_server (TLS Server). Cần đảm bảo OpenSSL của bạn đã cấu hình đúng cipher suite chứa Kyber (thường là TLS_AES_128_GCM_SHA256_KYBER768 hoặc tương tự tùy bản fork).
Khởi động một server TLS giả lập sử dụng Kyber cho handshake.
openssl s_server -accept 8443 -cert /tmp/kyber512.pem -key /tmp/kyber512.pem -cipher_list "TLS_AES_128_GCM_SHA256_KYBER768" -msg -tls1_3 &
sleep 2
Lưu ý: Nếu OpenSSL chuẩn chưa hỗ trợ cipher suite này, bạn cần dùng bản OpenSSL đã patch (như từ dự án OQS-OpenSSL) hoặc cấu hình kernel module để chuyển hướng. Giả sử bạn đang chạy kernel đã tích hợp Kyber và OpenSSL đã liên kết với crypto API của kernel.
Kết quả mong đợi: Server khởi động, hiển thị "Using default temp DH parameters" hoặc tương tự, và chờ kết nối. Nếu lỗi "unknown cipher", nghĩa là cipher suite chưa được định nghĩa trong cấu hình hiện tại.
Thử kết nối từ client sử dụng OpenSSL s_client.
openssl s_client -connect 127.0.0.1:8443 -cipher "TLS_AES_128_GCM_SHA256_KYBER768" -tls1_3 -msg
Kết quả mong đợi:
- Nếu thành công: Hiển thị "Protocol : TLSv1.3", "Cipher : TLS_AES_128_GCM_SHA256_KYBER768", và quá trình handshake diễn ra bình thường.
- Nếu thất bại: "alert: handshake failure" hoặc "no cipher match".
Để kiểm tra sâu hơn về tương thích với SSH (OpenSSH), ta cần cấu hình /etc/ssh/sshd_config để hỗ trợ key exchange Kyber. Lưu ý: OpenSSH chuẩn chưa hỗ trợ Kyber trực tiếp, cần dùng OpenSSH fork hoặc OQS-SSH.
Tạo file cấu hình sshd giả lập (nếu bạn đang dùng OQS-SSH).
cat > /tmp/sshd_kyber_config
Restart SSH service (nếu đang dùng OQS-SSH).
systemctl restart sshd
Kết quả mong đợi: SSH service khởi động lại thành công. Nếu dùng OpenSSH chuẩn, lệnh này sẽ báo lỗi "Invalid argument" vì chưa nhận diện thuật toán Kyber. Điều này xác nhận tính tương thích phụ thuộc vào phiên bản client/server.
Thực hiện kết nối SSH test.
ssh -o KexAlgorithms=curve25519-sha256,sntrup761_x25519-sha256 -o HostKeyAlgorithms=ssh-ed25519,sntrup761_ed25519 user@localhost
Kết quả mong đợi:
- Nếu thành công: Kết nối được thiết lập, hiển thị thông tin về key exchange sử dụng thuật toán lai (Hybrid).
- Nếu thất bại: "kex_exchange_identification: read: Connection reset by peer".
Verify kết quả: Kiểm tra log hệ thống /var/log/auth.log hoặc journalctl -u sshd để xem có thông báo về việc sử dụng thuật toán Post-Quantum trong quá trình handshake hay không.
grep -i "kyber\|sntrup\|pq" /var/log/auth.log | tail -n 5
Kết quả: Các dòng log xác nhận việc sử dụng thuật toán mã hóa mới trong quá trình xác thực mạng.
Điều hướng series:
Mục lục: Series: Triển khai Database Post-Quantum với Kyber trên Linux Kernel
« Phần 5: Triển khai Kernel mới và kích hoạt module mã hóa Kyber
Phần 7: Xử lý sự cố, tối ưu hóa và các mẹo nâng cao cho Kyber »