PKCS12, PEM หรือ DER: ไคลเอนต์ VPN ต้องการอะไรจริง ๆ
การบรรจุเป็นตัวกำหนดว่าไคลเอนต์ของคุณนำเข้าตัวตนได้หรือไม่ ไม่ใช่กำหนดว่าได้รับความเชื่อถือหรือเปล่า เปรียบเทียบ PKCS12, PEM และ DER แล้วตรวจสอบ
มีข้ออ้างสองข้อที่วนเวียนอยู่ในกระทู้เรื่องใบรับรอง ข้อแรกคือ .p12 เป็นตัวเลือกที่แข็งแรงและ .pem เป็นตัวที่หลวมกว่า ข้อที่สองคือไฟล์ข้อความต้องปลอดภัยที่จะส่งเพราะคุณอ่านมันได้ ไม่มีข้อใดทนการตรวจสอบได้แม้แต่นาทีเดียว
PKCS12, PEM และ DER อธิบายว่าวัตถุใบรับรองถูกบรรจุและเข้ารหัสรูปแบบอย่างไร มันไม่ได้ตัดสินว่าใครคือคู่สนทนา ผู้ออกได้รับความเชื่อถือหรือไม่ หรือไฟล์ต้องใช้รหัสผ่านหรือเปล่า
สิ่งที่ไคลเอนต์ยอมรับเป็นคำถามเรื่องความเข้ากันได้ สิ่งที่อยู่ในไฟล์เป็นคำถามเรื่องตัวตน แยกสองเรื่องนี้ออกจากกัน แล้วข้อผิดพลาดในการนำเข้าส่วนใหญ่จะไม่ลึกลับอีกต่อไป
สามคอนเทนเนอร์ หนึ่งแบบจำลองวัตถุ
เริ่มจากสิ่งที่คุณมีจริง ๆ ใบรับรองคือคำแถลงที่ลงนามแล้วเกี่ยวกับกุญแจสาธารณะ กุญแจส่วนตัวเป็นวัสดุแยกต่างหากที่พิสูจน์ว่าคุณควบคุมกุญแจนั้น ห่วงโซ่คือชุดผู้ออกที่เชื่อมใบรับรองของคุณกับรูทที่ไคลเอนต์เชื่อถือ ทั้งสามอย่างมีอยู่ไม่ว่าจะบรรจุแบบไหน
ไฟล์ PKCS12 ซึ่งมักเป็น .p12 หรือ .pfx คือคอนเทนเนอร์ที่กำหนดใน RFC 7292 ซึ่งบรรทุกกุญแจส่วนตัว ใบรับรองหนึ่งใบหรือมากกว่า และห่วงโซ่ ไว้ในก้อนเดียวที่ป้องกันด้วยรหัสผ่าน พร้อมชื่อแทนที่ระบุตัวตน ไฟล์ PEM คือกรอบข้อความที่กำหนดใน RFC 7468: เนื้อหา base64 ระหว่างบรรทัด BEGIN กับ END และไฟล์เดียวสามารถเก็บหลายบล็อกต่อกันได้ DER คือการเข้ารหัสแบบไบนารีของโครงสร้าง ASN.1 เดียวกัน และเนื้อหา PEM ก็คือ DER ที่ห่อด้วย base64 ตามตัวอักษร
ประโยคสุดท้ายนั้นคือประโยคที่ควรจดจำ การแปลง PEM เป็น DER เขียนกรอบใหม่ ไม่ใช่เนื้อหา และการแปลงกลับจะได้ไบต์เดิม
| Container | Can hold | Does not decide |
|---|---|---|
| PKCS12 (.p12, .pfx) | Key, leaf certificate, chain, alias, password | Which root the client trusts |
| PEM (.pem, .crt, .cer) | Any number of base64 blocks | Whether the private key is present |
| DER (.der, .cer) | One binary structure | The object type, whatever the extension says |
การเข้ารหัสรูปแบบไม่ใช่การเข้ารหัสลับ
Base64 คือชุดตัวอักษรสำหรับการขนส่ง มันไม่ได้ซ่อนอะไรเลย ใครก็ถอดรหัสบล็อก PEM ในเชลล์ได้ ไฟล์ DER เป็นไบนารีและเปิดเผยพอ ๆ กัน คุณสมบัติทั้งสองไม่ใช่การป้องกัน และไม่ได้บอกว่ามีรหัสผ่านอยู่
การป้องกันที่แท้จริงอยู่ในวัสดุกุญแจ ชุด PKCS12 สามารถเข้ารหัสเนื้อหาภายใต้กุญแจที่ได้มาจากรหัสผ่าน กุญแจส่วนตัวแบบ PEM สามารถเข้ารหัสด้วยบล็อกหัวแบบเก่าหรือเก็บไว้ใน PKCS#8 EncryptedPrivateKeyInfo ใบรับรองเพียงลำพังไม่มีความลับใด ๆ ซึ่งเป็นเหตุผลว่าการส่งออกที่ให้มาแค่ใบรับรองทำให้ไคลเอนต์ยืนยันตัวตนไม่ได้ ไม่ว่าคุณจะห่อด้วยรูปแบบใด
นามสกุลไฟล์เป็นเพียงคำใบ้ ไม่ใช่สัญญา ไฟล์ที่ลงท้ายด้วย .cer และ .crt ปรากฏในทั้งสองการเข้ารหัส และอุปกรณ์ส่งออกใบรับรอง DER ภายใต้ชื่อ .pem บ่อยพอที่จะทำให้การเดาจากนามสกุลเสียเวลาทั้งบ่าย ให้อ่านไบต์แรกแทน ไฟล์ PEM เริ่มด้วยบรรทัด BEGIN ขณะที่ DER เริ่มด้วย 0x30 เพราะโครงสร้างชั้นนอกเป็น SEQUENCE
ทำไมการนำเข้าจึงล้มเหลวจริง ๆ
ข้อความแสดงข้อผิดพลาดของไคลเอนต์บีบปัญหาหลายอย่างให้เป็นประโยคเดียวเกี่ยวกับใบรับรองที่ไม่ถูกต้อง ดังนั้นให้แยกตามสาเหตุ ที่พบบ่อยที่สุดคือการเข้ารหัสไม่ตรงกัน ไคลเอนต์ที่แยกวิเคราะห์ PEM จะคืนข้อผิดพลาดการแยกวิเคราะห์เมื่อเจอไฟล์ DER และวิธีแก้คือการแปลง ไม่ใช่ใบรับรองใหม่ อย่างที่สองคือกุญแจหาย ซึ่งใบรับรองยังดีอยู่แต่พิสูจน์ตัวตนไม่ได้ อย่างที่สามคือห่วงโซ่ ซึ่งชุดที่ไม่มีตัวกลางดูถูกต้องในกล่องนำเข้าแต่ล้มเหลวระหว่างแฮนด์เชก
พารามิเตอร์การเข้ารหัสลับก่อให้เกิดอย่างที่สี่ และมันดูเหมือนรหัสผ่านผิดทุกประการ อุปกรณ์รุ่นเก่าส่งออกไฟล์ PKCS12 ด้วย RC2-40 และ 3DES ซึ่ง OpenSSL 3 ปฏิเสธเว้นแต่จะโหลดผู้ให้บริการแบบเดิม การส่งออกใหม่จากอุปกรณ์ด้วย AES-256-CBC และ PBKDF2 คือวิธีแก้ที่ยั่งยืน การเปิดใช้รหัสลับแบบเดิมค้างไว้ถาวรบนเครื่องไคลเอนต์เพื่อรองรับไฟล์เดียวเป็นการแลกที่ไม่ดี
อย่างที่ห้าคือความกำกวม คอนเทนเนอร์ที่ถือกุญแจสองดอกและใบรับรองสองใบ หรือไฟล์ PEM ที่มีบล็อก CERTIFICATE สามบล็อก บังคับให้ไคลเอนต์เลือก และบ่อยครั้งที่มันเลือกแค่รายการแรก เมื่ออุโมงค์ขึ้นมาด้วยตัวตนผิด นั่นมักเป็นเหตุผล
ตรวจดูก่อนแปลง
อ่านโครงสร้างโดยไม่พิมพ์ความลับ openssl pkcs12 -in bundle.p12 -info -noout รายงานอัลกอริทึมการเข้ารหัสลับและชื่อแทนพร้อมระงับผลลัพธ์ของกุญแจและใบรับรอง และ คู่มือ openssl-pkcs12 อธิบายแฟล็กต่าง ๆ การตัด -noout ออกและเพิ่ม -nodes ใช้สำหรับสร้างไฟล์ที่คุณตั้งใจจะเก็บ ไม่ใช่สำหรับดูเร็ว ๆ เพราะมันเขียนกุญแจส่วนตัวแบบเปิดเผย
สำหรับใบรับรอง openssl x509 -in cert.pem -noout -subject -issuer -dates ตอบสิ่งที่กล่องนำเข้าตอบไม่ได้ และการเพิ่ม -ext subjectAltName จะแสดงชื่อที่ใบรับรองใช้ได้จริง ถ้าไฟล์เป็น DER ให้เพิ่ม -inform DER แฟล็กเดียวนี้แก้ข้อผิดพลาดแบบโหลดไม่ได้ส่วนใหญ่ได้
การจับคู่กุญแจกับใบรับรองเป็นเรื่องกลไก และคุ้มค่าที่จะทำก่อนนำเข้า:
openssl x509 -in cert.pem -noout -pubkey | openssl sha256openssl pkey -in key.pem -pubout | openssl sha256
ค่าแฮชที่เหมือนกันหมายความว่าคู่นั้นเป็นของคู่กัน ค่าแฮชที่ต่างกันหมายความว่าคุณมีกุญแจผิด และการแปลงรูปแบบเท่าไรก็ไม่เปลี่ยนสิ่งนั้น
สิ่งที่รูปแบบไม่เคยเปลี่ยน
การตัดสินใจเรื่องความเชื่อถือเกิดขึ้นเหนือคอนเทนเนอร์ ไคลเอนต์ไล่ห่วงโซ่ไปยังรูทในที่เก็บของมัน ตรวจช่วงเวลาที่ใช้ได้ ตรวจการใช้กุญแจแบบขยายสำหรับการยืนยันตัวตนของไคลเอนต์ และฝั่งเซิร์ฟเวอร์ตรวจว่าชื่อที่มันเรียกไปปรากฏในใบรับรอง ไม่มีขั้นตอนใดอ่านนามสกุลไฟล์
นั่นคือเหตุผลที่การเปลี่ยนชื่อไฟล์จนข้อผิดพลาดหายไปเป็นวิธีเสียเวลาที่เชื่อถือได้ การนำเข้าสำเร็จ ตัวตนยังผิดอยู่ และความล้มเหลวกลับมาในระหว่างแฮนด์เชกซึ่งข้อความช่วยได้น้อยกว่า ยังเป็นเหตุผลที่ชุดที่ส่งออกเมื่อสองปีก่อนนำเข้าได้สะอาดและยังถูกปฏิเสธ วันที่หมดอายุเดินทางอยู่ในใบรับรอง ไม่ใช่ในชื่อไฟล์
ลำดับที่หลีกเลี่ยงการทำงานซ้ำ
ถามเอกสารของไคลเอนต์ว่ามันยอมรับการเข้ารหัสแบบใดและคาดหวังคอนเทนเนอร์แบบใดสำหรับตัวตนของไคลเอนต์ แล้วดูว่าคุณได้รับอะไรมา ถ้าไคลเอนต์ต้องการตัวตนเดียวที่นำเข้าได้และคุณมีไฟล์ PEM แยก ๆ อยู่ ให้สร้างชุดหนึ่งครั้งด้วยรหัสผ่านที่คุณควบคุมและเก็บต้นฉบับไว้ ถ้ามันต้องการ PEM ให้แยกกุญแจและห่วงโซ่ออก แล้วลบไฟล์กลางทิ้งภายหลังผ่านกระบวนการจัดการข้อมูลรับรองที่ทีมของคุณใช้อยู่แล้ว
หลังนำเข้า ให้ตรวจสอบตัวตนไม่ใช่กล่องโต้ตอบ: หัวเรื่อง ผู้ออก วันหมดอายุ และชื่อที่ไคลเอนต์จะนำเสนอ ชื่อที่อ่านง่ายในรายการเป็นเพียงป้ายกำกับ ไม่ใช่ตัวตนที่ตรวจสอบแล้ว ถ้าอุโมงค์ล้มเหลวหลังจากนั้น คุณกำลังแก้ปัญหาการยืนยันตัวตนหรือการกำหนดเส้นทาง ไม่ใช่การบรรจุ ซึ่งเป็นบทสนทนาที่สั้นกว่ามาก