บทความ › ความปลอดภัย

Post-quantum บน SSH และ HTTPS: ML-KEM คืออะไร และเช็กเซิร์ฟเวอร์ของเรายังไง

OpenSSH 10 ใช้ mlkem768x25519 เป็นค่าเริ่มต้นแล้ว 10.1 เตือนเมื่อไม่ได้ใช้ เบราว์เซอร์ก็ใช้ X25519MLKEM768 วิธีเช็กว่าเซิร์ฟเวอร์ตกลงใช้อะไรจริง และต้องอัปเกรดอะไร

กลาง อ่าน 8 นาที 23 ตุลาคม 2569

อ่านจบแล้วจะรู้
  • OpenSSH 10.0 (เมษายน 2025) ใช้ mlkem768x25519-sha256 เป็นค่าเริ่มต้น ส่วน 10.1 ขึ้นคำเตือนเมื่อการเชื่อมต่อไม่ได้ใช้ key exchange แบบ post-quantum
  • แบบ hybrid ผสม ML-KEM กับ X25519 ถ้า ML-KEM ถูกเจาะในอนาคต ก็ยังแข็งเท่า X25519 เดิม ไม่ได้อ่อนลง
  • เช็กได้ด้วย ssh -v ดูบรรทัด kex algorithm และฝั่ง HTTPS ใช้ openssl s_client จาก OpenSSL 3.5 ขึ้นไป
  • Ubuntu 24.04 ยังได้แค่ sntrup761 สำหรับ SSH และยังไม่มี PQ บน HTTPS จาก OpenSSL ของระบบ ต้องขึ้น 26.04 หรือ Debian 13

“Post-quantum” ฟังดูไกลตัว แต่มันมาถึงเครื่องเราแล้วแบบเงียบ ๆ ตั้งแต่ OpenSSH 10.0 (เมษายน 2025) การเชื่อมต่อ SSH ใช้ key exchange แบบผสม ML-KEM กับ X25519 เป็นค่าเริ่มต้น และ OpenSSH 10.1 เริ่มขึ้นคำเตือนเมื่อเซิร์ฟเวอร์ปลายทางยังไม่รองรับ ฝั่งเว็บ Chrome ส่ง X25519MLKEM768 ไปกับการเชื่อมต่อ HTTPS มาตั้งแต่รุ่น 131 บทความนี้อธิบายว่ามันกันอะไร เช็กเซิร์ฟเวอร์ตัวเองยังไง และต้องอัปเกรดอะไรบ้าง

ทดสอบบน: OpenSSH_9.7p1 (Windows) รัน ssh -Q kex และ ssh -v จริง เวอร์ชันแพ็กเกจของ Ubuntu/Debian ตรวจกับ Launchpad และ packages.debian.org ณ ตุลาคม 2026 ข้อมูล OpenSSH ตรวจกับ openssh.org (รุ่นล่าสุดคือ 10.6 ออกเมื่อ 6 ตุลาคม 2026)

กันอะไร: store now, decrypt later

key exchange คือขั้นที่สองฝั่งตกลงกุญแจลับของ session โดยคนดักฟังรู้ไม่ได้ วิธีที่ใช้กันตอนนี้ (X25519, ECDH) ปลอดภัยกับคอมพิวเตอร์ปกติ แต่คณิตศาสตร์ที่อยู่ข้างใต้จะถูกแก้ได้ด้วยควอนตัมคอมพิวเตอร์ขนาดใหญ่พอ

ยังไม่มีเครื่องแบบนั้น แต่หน้า post-quantum ของ OpenSSH อธิบายภัยที่เกิดแล้ววันนี้ คือคนที่ ดักเก็บ traffic ที่เข้ารหัสไว้ตอนนี้ แล้วรอถอดในวันที่มีเครื่อง เรียกว่า store now, decrypt later ข้อมูลที่วิ่งผ่าน SSH หรือ HTTPS วันนี้จึงเสี่ยงตั้งแต่วันนี้ ถ้าไม่ได้ใช้ key exchange แบบ post-quantum

สิ่งที่ไม่ต้องรีบคือ ลายเซ็นและ key ยืนยันตัวตน (host key, user key, ใบรับรอง TLS) เพราะการปลอมตัวต้องทำตอนเชื่อมต่อ ทำย้อนหลังไม่ได้ ใช้ ed25519 เดิมต่อไปได้

ML-KEM + X25519ทนควอนตัมML-KEM พัง ยังมี X25519เพิ่ม ~2.3 KB ต่อครั้งX25519 อย่างเดียวปลอดภัยวันนี้ควอนตัมเจาะได้ดักเก็บวันนี้ ถอดทีหลัง
hybrid ไม่มีทางแย่กว่าของเดิม

ML-KEM และทำไมต้อง hybrid

ML-KEM คือมาตรฐาน key encapsulation แบบทนควอนตัมของ NIST (FIPS 203 พัฒนามาจาก Kyber) ชื่อ mlkem768x25519 บอกว่ามันใช้ สองอย่างพร้อมกัน ML-KEM-768 กับ X25519 แล้วรวมผลเป็นกุญแจเดียว

หน้า pq.html ของ OpenSSH ให้เหตุผลว่า แบบ hybrid รับประกันว่าไม่แย่กว่าของเดิม ถ้าวันหนึ่งพบว่า ML-KEM มีจุดอ่อน ก็ยังมี X25519 ค้ำอยู่ ถ้าควอนตัมเจาะ X25519 ได้ ก็ยังมี ML-KEM

ชื่อใช้ที่ค่าเริ่มต้นตั้งแต่
sntrup761x25519-sha512@openssh.comSSHOpenSSH 9.0 (เมษายน 2022)
mlkem768x25519-sha256SSHมีใน 9.9 เป็นค่าเริ่มต้นใน 10.0 (เมษายน 2025)
X25519MLKEM768TLS 1.3 / HTTPSChrome 131, OpenSSL 3.5 (เมษายน 2025)

ฝั่ง TLS ชื่อ X25519MLKEM768 มีมาตรฐานเป็น RFC 10024 แล้ว ใช้รหัส 0x11EC

ตัวอย่างคำนวณ: ส่งข้อมูลเพิ่มเท่าไร

ขนาดตามมาตรฐาน ML-KEM-768: public key 1,184 ไบต์ ciphertext 1,088 ไบต์ ส่วน X25519 ใช้ 32 ไบต์ต่อฝั่ง

  1. ฝั่ง client ส่ง: 1,184 + 32 = 1,216 ไบต์ (ตรงกับขนาด client share ใน RFC 10024)
  2. ฝั่ง server ตอบ: 1,088 + 32 = 1,120 ไบต์
  3. รวมสองทาง: 1,216 + 1,120 = 2,336 ไบต์ ≈ 2.3 KB
  4. เทียบกับ X25519 อย่างเดียว: 32 + 32 = 64 ไบต์ เพิ่มขึ้นราว 2.27 KB ต่อการเชื่อมต่อ

จ่ายครั้งเดียวตอนเริ่ม session หลังจากนั้นข้อมูลทั้งหมดเข้ารหัสด้วย cipher เดิม (เช่น chacha20-poly1305 หรือ AES-GCM) ไม่มีค่าใช้จ่ายเพิ่ม

เช็ก SSH: ตกลงใช้อะไรจริง

# client เรารองรับอะไรบ้าง
ssh -Q kex | grep -E 'mlkem|sntrup'

# ต่อจริงแล้วดูว่าตกลงได้อะไร
ssh -v user@server.example.com exit 2>&1 | grep 'kex: algorithm'

ผลที่ได้บนเครื่องทดสอบ (client 9.7 ซึ่งยังไม่มี mlkem) ต่อไปยัง github.com

debug1: kex: algorithm: sntrup761x25519-sha512@openssh.com

ถ้าเห็น mlkem768x25519-sha256 หรือ sntrup761x25519-sha512@openssh.com แปลว่าเป็น post-quantum แล้ว ถ้าเห็น curve25519-sha256 หรือ ecdh-sha2-nistp256 แปลว่ายังไม่ใช่

ฝั่งเซิร์ฟเวอร์ ดูค่าที่ sshd ใช้จริงหลังรวมทุกไฟล์ config

sudo sshd -T | grep -i kexalgorithms

ถ้ามีแต่ curve25519 กับ diffie-hellman ให้หาว่าใครตั้ง KexAlgorithms ไว้ใน /etc/ssh/sshd_config หรือ /etc/ssh/sshd_config.d/ คู่มือ hardening เก่า ๆ มักให้ตั้งรายการตายตัว ซึ่งตัด post-quantum ทิ้งโดยไม่ตั้งใจ หน้า pq.html เองแนะนำให้เช็กจุดนี้เป็นอย่างแรก

ค่าเริ่มต้นของ OpenSSH รุ่นใหม่ดีกว่ารายการที่เราเขียนเอง ถ้าไม่มีเหตุผลเฉพาะ ลบบรรทัด KexAlgorithms ออก แล้วให้ค่าเริ่มต้นทำงาน

ขั้นตอน hardening อื่น เช่น ปิด password login ดูได้ที่ ตั้งค่า SSH ให้ปลอดภัย ซึ่งใช้คู่กันได้โดยไม่ขัดกัน

คำเตือนใน OpenSSH 10.1

ถ้า client เป็น 10.1 ขึ้นไป แล้วต่อเซิร์ฟเวอร์ที่ไม่รองรับ PQ จะเห็นข้อความขึ้นต้นด้วย

** WARNING: connection is not using a post-quantum key exchange algorithm.

ทางแก้ที่ถูกคืออัปเกรดเซิร์ฟเวอร์ ถ้าเป็นอุปกรณ์ที่อัปเกรดไม่ได้ (router, NAS รุ่นเก่า) ปิดคำเตือนเฉพาะเครื่องนั้นใน ~/.ssh/config ตามที่ pq.html แนะนำ อย่าปิดทั้งหมด

Match host old-nas.example.com
    WarnWeakCrypto no-pq-kex

เช็ก HTTPS

Chrome รุ่นปัจจุบันเสนอ X25519MLKEM768 อยู่แล้ว เหลือแค่ฝั่งเซิร์ฟเวอร์ ต้องใช้ OpenSSL 3.5 ขึ้นไปทั้งตอนเช็กและตอนเสิร์ฟ

# ต้องใช้ openssl 3.5+ ฝั่งเครื่องที่รันคำสั่ง
echo | openssl s_client -connect example.com:443 -tls1_3 2>/dev/null \
  | grep 'Negotiated TLS1.3 group'

ได้ X25519MLKEM768 แปลว่าเซิร์ฟเวอร์รองรับ ไม่มีบรรทัดนี้หรือได้ X25519 แปลว่ายัง อีกทางคือเปิด DevTools ของ Chrome แท็บ Security ดูช่อง key exchange

nginx มีค่าเริ่มต้น ssl_ecdh_curve auto ซึ่งตามเอกสาร nginx คือให้ใช้รายการที่มากับ OpenSSL ถ้า nginx ลิงก์กับ OpenSSL 3.5 และไม่มีใครตั้งค่านี้ทับ ก็ควรได้ PQ เอง แต่ถ้า config มีบรรทัดอย่าง ssl_ecdh_curve secp384r1; จากคู่มือเก่า ให้ลบออกหรือเพิ่ม X25519MLKEM768 ไว้หน้าสุด แล้วเช็กด้วยคำสั่งข้างบนอีกครั้ง

ระบบไหนได้อะไร

ระบบOpenSSHOpenSSLSSH PQHTTPS PQ (OpenSSL ระบบ)
Ubuntu 22.048.93.0ต้องเช็กไม่
Ubuntu 24.049.63.0sntrup761ไม่
Ubuntu 26.0410.23.5mlkem768ได้
Debian 129.23.0sntrup761ไม่
Debian 1310.03.5mlkem768ได้

เวอร์ชันจาก Launchpad และ packages.debian.org ณ ตุลาคม 2026 ช่อง SSH PQ คือค่าเริ่มต้นตามเวอร์ชัน (9.0+ ได้ sntrup761, 10.0+ ได้ mlkem768) Ubuntu 22.04 ใช้ 8.9 ซึ่งเก่ากว่า 9.0 ที่ PQ เป็นค่าเริ่มต้น ให้รัน sshd -T ดูเอง

ข้อผิดพลาดที่เจอบ่อย

  • ตั้ง KexAlgorithms ตายตัว จากคู่มือปี 2020 แล้วลืม เครื่องอัปเกรดแล้วก็ยังไม่ได้ PQ
  • ปิด WarnWeakCrypto ทั้งระบบ เพราะรำคาญ แล้วไม่รู้อีกเลยว่าเครื่องไหนยังเก่า
  • เช็ก HTTPS ด้วย openssl รุ่นเก่า OpenSSL 3.0 ไม่รู้จัก X25519MLKEM768 ผลจะบอกว่าไม่รองรับทั้งที่เซิร์ฟเวอร์รองรับ
  • รีบเปลี่ยน host key หรือใบรับรอง ยังไม่จำเป็น ส่วนที่ต้องรีบคือ key exchange
  • ลืมเครื่องหลัง load balancer ถ้า TLS ไปจบที่ CDN หรือ load balancer สิ่งที่ผู้ใช้เห็นคือของตัวนั้น ไม่ใช่ nginx ของเรา

แหล่งอ้างอิง

คำถามที่พบบ่อย

ควอนตัมคอมพิวเตอร์ยังเจาะอะไรไม่ได้ ทำไมต้องรีบ

เพราะคนที่ดักเก็บ traffic ที่เข้ารหัสไว้วันนี้ เอาไปถอดได้ในวันที่มีเครื่องพอ เรียกว่า store now, decrypt later ข้อมูลที่ต้องเป็นความลับอีกหลายปี เช่น รหัสผ่านหรือข้อมูลลูกค้าที่วิ่งผ่าน SSH วันนี้ จึงเสี่ยงตั้งแต่วันนี้ ไม่ใช่วันที่เครื่องควอนตัมเสร็จ

ต้องเปลี่ยน SSH key เป็นแบบ post-quantum ด้วยไหม

ยังไม่ต้อง สิ่งที่ OpenSSH เปลี่ยนคือ key exchange ที่ใช้สร้างกุญแจเข้ารหัสของแต่ละ session ซึ่งเป็นส่วนที่ถูกดักเก็บแล้วถอดทีหลังได้ ส่วน host key และ user key ใช้ยืนยันตัวตนตอนเชื่อมต่อ ปลอมย้อนหลังไม่ได้ ใช้ ed25519 เดิมต่อได้

เปิดแล้วช้าลงไหม

แทบไม่รู้สึก ข้อมูลที่ส่งเพิ่มคือ key share ราว 2.3 KB ต่อการเชื่อมต่อหนึ่งครั้ง (คำนวณในบทความ) หลังจากนั้นการเข้ารหัสข้อมูลใช้ cipher เดิมทุกอย่าง

คำสั่งและค่าตั้งในบทความทดสอบบนระบบตัวอย่าง ลองบนเครื่องทดสอบก่อนใช้กับระบบจริงเสมอ

อ่านต่อ

#Securityเริ่มต้น

ใบรับรอง SSL/TLS อายุสั้นลงเหลือ 47 วัน: ไทม์ไลน์ 2026-2029 และต้องทำอะไร

CA/B Forum ลดอายุใบรับรอง TLS จาก 398 วันเหลือ 47 วันภายในปี 2029 ส่วน Let's Encrypt มีใบ 6 วันและใบสำหรับ IP แล้ว สรุปไทม์ไลน์ และวิธีตั้งต่ออายุอัตโนมัติ

อ่าน 9 นาที
#Securityเริ่มต้น

เช่าเซิร์ฟเวอร์มาใหม่ ตั้งค่า SSH ให้ปลอดภัยใน 7 ขั้นตอน

ทำทันทีหลังได้เซิร์ฟเวอร์ Ubuntu ใหม่ สร้างผู้ใช้ ใช้คีย์แทนรหัสผ่าน ปิดล็อกอิน root เปิดไฟร์วอลล์ fail2ban และอัปเดตอัตโนมัติ พร้อมกับดักที่หลายคนพลาด

อ่าน 4 นาที
#Securityกลาง

กัน CSRF โดยไม่ต้องใช้ token ด้วย Sec-Fetch-Site และ Origin (Go 1.25)

เบราว์เซอร์ยุคนี้บอกเซิร์ฟเวอร์เองว่าคำขอมาจากเว็บอื่นหรือเปล่า เช็กหัว Sec-Fetch-Site กับ Origin แทน CSRF token ได้ วิธีทำใน Go 1.25 และข้อแม้ที่ต้องรู้

อ่าน 10 นาที