เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ · URL ตัวเข้ารหัสและตัวถอดรหัส
Punycode เทียบกับการเข้ารหัสเปอร์เซ็นต์: วิธีจัดการโดเมนและเส้นทางที่ไม่ใช่ ASCII
· พื้นหลัง
ความเป็นสากล Punycode การเข้ารหัส URL
URL ที่มีชื่อโฮสต์ที่ไม่ใช่ ASCII และเส้นทางที่ไม่ใช่ ASCII ใช้การเข้ารหัสที่แตกต่างกันโดยสิ้นเชิงสองแบบ โพสต์นี้จะอธิบาย IDNA และ punycode สำหรับโฮสต์ การเข้ารหัสเปอร์เซ็นต์สำหรับทุกสิ่งทุกอย่าง และเหตุใดจึงมีการแบ่งแยก
ที่อยู่ที่แสดง 'münchen.example' ในเบราว์เซอร์หนึ่งและ 'xn--mnchen-3ya.example' ในอีกเบราว์เซอร์หนึ่ง — หนึ่งโฮสต์ การสะกดสองครั้ง
เมือง München ปรากฏในชื่อโดเมนภาษาเยอรมัน ในแถบที่อยู่ของเบราว์เซอร์ คุณอาจเห็น münchen.example แสดงตามปกติ คัดลอกที่อยู่จากแอปพลิเคชันอื่น และปรากฏเป็น xn--mnchen-3ya.example ซึ่งเป็นสตริง ASCII เท่านั้นที่ดูไม่เหมือนข้อความภาษาเยอรมัน หนึ่ง URL การสะกดสองครั้ง ถูกต้องทั้งคู่ ไม่มีอะไรผิด พวกเขาเป็นตัวแทนของโดเมนเดียวกันโดยใช้ชุดอักขระที่แตกต่างกันโดยสิ้นเชิง ความแตกต่างนี้สะท้อนถึงข้อจำกัดพื้นฐานเกี่ยวกับวิธีการทำงานของ DNS และวิธีที่โครงสร้างพื้นฐานอินเทอร์เน็ตคาดหวังให้ชื่อโฮสต์ถูกส่ง
ส่วนเส้นทางเช่น /café/ จำเป็นต้องมีการเข้ารหัส แต่ใช้ระบบอื่น Non-ASCII é กลายเป็น %C3%A9 ในเส้นทาง ทำไมความแตกต่าง? ข้อจำกัด DNS ต้องใช้ punycode สำหรับชื่อโฮสต์
เหตุใดชื่อโฮสต์จึงไม่สามารถใช้การเข้ารหัสเปอร์เซ็นต์ได้ — ป้ายกำกับ DNS อักขระที่อนุญาต และขีดจำกัดความยาว
ป้ายกำกับ DNS ซึ่งเป็นแต่ละส่วนของชื่อโฮสต์ที่คั่นด้วยจุด มีกฎที่เข้มงวดมาก สามารถมีได้เพียง ASCII ตัวอักษร ตัวเลข ขีดกลาง และขีดล่างเท่านั้น มีการจำกัดความยาว: แต่ละป้ายกำกับมีความยาวได้สูงสุด 63 octets และชื่อโฮสต์แบบเต็มต้องไม่เกิน 255 octets สิ่งเหล่านี้เป็นข้อจำกัดที่ยากจากโปรโตคอล DNS เอง ซึ่งกำหนดไว้เมื่อหลายสิบปีก่อนก่อนที่ชื่อโดเมนระหว่างประเทศจะเป็นแนวคิดด้วยซ้ำ การเข้ารหัสเปอร์เซ็นต์ไม่สามารถใช้กับชื่อโฮสต์ได้ เนื่องจากสตริงผลลัพธ์อาจเกินขีดจำกัดป้ายกำกับสำหรับคำที่ยาวกว่า
ที่สำคัญกว่านั้น DNS เป็นระบบสากลที่ดำเนินการโดยเราเตอร์และเซิร์ฟเวอร์ทั่วโลก ไม่ใช่ทั้งหมดที่จะเข้าใจ UTF-8 หรือ Unicode อักขระที่เข้ารหัสเปอร์เซ็นต์ เช่น %C3%A9 ยังคงเป็นอักขระ ASCII สามตัว ดังนั้นจึงสอดคล้องกับข้อจำกัด DNS แต่วิธีการดังกล่าวหมายความว่าการค้นหาทุกครั้งจะต้องเข้ารหัสเปอร์เซ็นต์ระหว่างทางเข้าและถอดรหัสเมื่อทางออก เพื่อเพิ่มความซับซ้อนให้กับเลเยอร์โปรโตคอลเอง จำเป็นต้องมีโซลูชันที่ดีกว่าสำหรับชื่อโฮสต์โดยเฉพาะ
IDNA และ punycode ในโครงร่าง - คำนำหน้า xn-- และอัลกอริธึม bootstring อธิบายในเชิงคุณภาพ
IDNA เป็นข้อกำหนดเฉพาะของชื่อโดเมนสากลในแอปพลิเคชัน แก้ไขปัญหาชื่อโฮสต์โดยการเข้ารหัสชื่อโดเมนที่ไม่ใช่ ASCII ลงใน ASCII ที่ DNS สามารถจัดการได้ การเข้ารหัสที่ใช้เรียกว่า punycode ซึ่งเป็นอัลกอริธึมการบีบอัดที่เปลี่ยนข้อความ Unicode ให้เป็น ASCII โดยใช้คำนำหน้า xn ตามด้วยการแสดงที่เข้ารหัสด้วย bootstring อัลกอริทึมถูกกำหนดไว้: münchen จะกลายเป็น xn--mnchen-3ya เสมอทุกครั้ง ชื่อโฮสต์ที่ไม่ใช่ ASCII จะต้องแปลงด้วยวิธีนี้ก่อนจึงจะสามารถแก้ไข DNS ได้
คำนำหน้า xn-- ส่งสัญญาณไปยัง DNS และไปยัง IDNA- ซอฟต์แวร์ที่ทราบว่าอักขระต่อไปนี้เป็น punycode ไม่ใช่ตัวอักษร ASCII ตัวอักษร โดเมนเช่น example.xn--mnchen-3ya.com เข้าใจว่าหมายถึง example.münchen.com โดย IDNA-ซอฟต์แวร์ที่รับรู้ Punycode ใช้เพียง ASCII ตัวอักษร ตัวเลข และขีดกลางเท่านั้น ดังนั้นจึงพอดีกับป้ายกำกับ DNS ได้อย่างไม่มีปัญหา อัลกอริทึมจะบีบอัดข้อมูลที่ไม่ใช่ ASCII ลงในการแสดง ASCII นี้
เส้นทาง ข้อความค้นหา และส่วนต่างๆ ยังคงเข้ารหัสเป็นเปอร์เซ็นต์ — UTF-8 ไบต์ถึง %XX เช่นเดียวกับที่อื่นๆ
สิ่งอื่นๆ ใน URL ได้แก่ เส้นทาง สตริงการสืบค้น ส่วนย่อย จะใช้การเข้ารหัสเปอร์เซ็นต์แทน อักขระที่ไม่ใช่ ASCII จะถูกแปลงเป็นไบต์ UTF-8 ก่อน จากนั้นแต่ละไบต์จะถูกเขียนเป็น %HH โดยที่ HH เป็นเลขฐานสิบหก เส้นทาง /café/ กลายเป็น /caf%C3%A9/. สตริงการสืบค้น ?name=josé กลายเป็น ?name=jos%C3%A9 การเข้ารหัสเปอร์เซ็นต์เป็นมาตรฐานทุกที่บนเว็บ: ใน HTTP URL คำขอ ในรูปแบบ HTML ใน API ไม่ต้องการการจัดการพิเศษโดย DNS หรือเราเตอร์
การเข้ารหัสเปอร์เซ็นต์ยังช่วยให้สามารถแสดงอักขระพิเศษอื่นๆ ได้อย่างปลอดภัย ช่องว่างจะกลายเป็น %20 เครื่องหมายทับ (หากต้องปรากฏภายในค่า) จะกลายเป็น %2F และอื่นๆ โครงการมีความสอดคล้องและเป็นสากล ไม่ได้ใช้สำหรับชื่อโฮสต์เนื่องจาก DNS ไม่เข้าใจ URL หรือการเข้ารหัสเปอร์เซ็นต์ เข้าใจเพียงป้ายกำกับ ASCII เท่านั้น
ตัวอย่างการทำงาน: หนึ่ง URL ที่มีทั้งสองอย่าง - โฮสต์แปลงเป็น punycode, เส้นทางที่เข้ารหัสเปอร์เซ็นต์, เคียงข้างกัน
ใช้ URL "https://münchen.example/café?city=münchen". ชื่อโฮสต์ münchen จะต้องแปลงเป็น Punycode ก่อนการค้นหา DNS: https://xn--mnchen-3ya.example/café?city=münchen. แต่เดี๋ยวก่อน เส้นทางและข้อความค้นหาก็ไม่ใช่-ASCII แปลงสิ่งเหล่านั้นด้วย: https://xn--mnchen-3ya.example/caf%C3%A9?city=m%C3%BCnchen. ตอนนี้ชื่อโฮสต์คือ punycode เส้นทางและข้อความค้นหามีการเข้ารหัสเปอร์เซ็นต์ เบราว์เซอร์แสดงเวอร์ชัน Unicode ดั้งเดิมเพื่อให้สามารถอ่านได้ คำขอ HTTP มีเวอร์ชันที่เข้ารหัส
ในเครื่องมือตัวเข้ารหัสและตัวถอดรหัส URL ให้วางเส้นทางที่มีข้อความที่ไม่ใช่ ASCII และเปรียบเทียบโหมดค่าเดียว (เฉพาะเส้นทาง) กับโหมดที่อยู่ทั้งหมด (URL แบบเต็ม) เครื่องมือจะแสดงผลลัพธ์ที่เข้ารหัสเป็นเปอร์เซ็นต์สำหรับเส้นทาง อย่างไรก็ตาม ชื่อโฮสต์ต้องมีการแปลง punycode แยกต่างหาก เครื่องมือเข้ารหัสส่วนใหญ่ไม่สามารถจัดการแบบอินไลน์ได้ ดังนั้นโปรดอ่านจากเอกสารประกอบของเครื่องมือ
การโจมตีแบบ Homograph และสาเหตุที่บางครั้งเบราว์เซอร์แสดง Punycode — เหตุผลด้านความปลอดภัยที่อยู่เบื้องหลังกฎการแสดงผล
ผู้ประสงค์ร้ายสามารถจดทะเบียนโดเมนโดยใช้ตัวอักษรซีริลลิกที่ดูเหมือนกับตัวอักษรละติน เช่น "https://xn--80akhbyknj4f.example" (เวอร์ชันซีริลลิกของ "example.example" ใน punycode) หากเบราว์เซอร์แสดงโดเมนที่ถอดรหัสเป็นข้อความซีริลลิก ผู้ใช้อาจไม่สังเกตเห็นความแตกต่าง เพื่อป้องกันการโจมตีด้วยคำพ้องเสียง บางครั้งเบราว์เซอร์จะแสดงเวอร์ชัน punycode แทนการถอดรหัส มีคำเตือนปรากฏขึ้น: โดเมนนี้เป็นทั้งหมดหรือเป็นส่วนใหญ่ ไม่ใช่-ASCII และคุณอาจจำอักขระไม่ได้
ตัวเข้ารหัสและตัวถอดรหัส URL เป็นเครื่องมือสำหรับการเข้ารหัสและถอดรหัส ไม่ใช่สำหรับการประเมินความปลอดภัย หากคุณกำลังทำงานกับชื่อโดเมนระหว่างประเทศ โปรดทราบว่าการแสดง punycode คือสิ่งที่เครือข่ายเห็น
สิ่งนี้ไม่ครอบคลุมถึง — การรันอัลกอริทึม punycode ด้วยมือหรือความแตกต่าง IDNA 2003 กับ 2008
IDNA ผ่านหลายเวอร์ชันเมื่อเวลาผ่านไป: IDNA 2003 และ IDNA 2008 จัดการ Edge Case บางกรณีที่แตกต่างกัน โดยเฉพาะอย่างยิ่งในช่วงการทำให้เป็นมาตรฐานและอักขระ Unicode ที่ได้รับอนุญาตตามข้อกำหนด ระบบเก่าบางระบบยังคงใช้ IDNA 2003 ในขณะที่ระบบอื่นๆ ได้ย้ายไปยัง IDNA 2008 เพื่อการปฏิบัติตามข้อกำหนดที่ดีขึ้น ความแตกต่างมีความสำคัญอย่างมากหากคุณกำลังสร้างระบบที่ต้องเข้ากันได้กับหลายเวอร์ชัน ตรวจสอบความต้องการของระบบของคุณอย่างรอบคอบอยู่เสมอ
Punycode ใช้การบีบอัดบูตสตริง มีการใช้งานในภาษาทั่วไป แต่ตรวจสอบนโยบาย IDNA ด้วยระบบชื่อโฮสต์ของคุณ ทดสอบความละเอียดและพฤติกรรมการแสดงผลแทนที่จะคิดไปเอง
ประเด็นสำคัญ: การเข้ารหัสสองครั้งสำหรับสองงาน — ตัวเข้ารหัสและตัวถอดรหัส URL จัดการส่วนที่เข้ารหัสเป็นเปอร์เซ็นต์อย่างไร และเหตุใดตัวเข้ารหัสเปอร์เซ็นต์จึงเป็นเครื่องมือที่ไม่ถูกต้องสำหรับชื่อโฮสต์
ชื่อโฮสต์จำเป็นต้องมี Punycode เนื่องจาก DNS เป็นโปรโตคอลเก่าที่เข้าใจเฉพาะป้ายกำกับ ASCII และมีความยาวและข้อจำกัดของอักขระที่เข้มงวด เส้นทาง ข้อความค้นหา และแฟรกเมนต์ใช้การเข้ารหัสเปอร์เซ็นต์ เนื่องจากเป็นแบบสากลบนเว็บและไม่มีข้อจำกัดเหล่านั้น เป็นวิธีแก้ปัญหาสองข้อที่แยกจากกันสำหรับปัญหาสองข้อที่แตกต่างกันโดยสิ้นเชิง เมื่อคุณพบ non-ASCII URL ชื่อโฮสต์จะได้รับการแปลง punycode ก่อน จากนั้นส่วนที่เหลือจะใช้การเข้ารหัสเปอร์เซ็นต์
สำหรับงานพัฒนาส่วนใหญ่ เฟรมเวิร์กหรือไลบรารีของคุณจะจัดการการแปลงนี้เบื้องหลังโดยอัตโนมัติ แต่การทำความเข้าใจว่าเหตุใดจึงมีการเข้ารหัสที่แตกต่างกันสองแบบจะช่วยป้องกันความสับสนเมื่อแก้ไขจุดบกพร่อง URL ต่างประเทศหรือนำโค้ดการจัดการ URL ของคุณไปใช้สำเร็จ