RFC2617 ระบุว่าจะเข้ารหัสชื่อผู้ใช้และรหัสผ่านเป็น base64 แต่ไม่ได้บอกว่าจะใช้การเข้ารหัสอักขระใดเมื่อสร้างอ็อกเต็ตสำหรับอินพุตในอัลกอริทึม base64
ฉันควรถือว่า US-ASCII หรือ UTF8? หรือมีคนตัดสินคำถามนี้ไปแล้วบ้าง?
RFC2617 ระบุว่าจะเข้ารหัสชื่อผู้ใช้และรหัสผ่านเป็น base64 แต่ไม่ได้บอกว่าจะใช้การเข้ารหัสอักขระใดเมื่อสร้างอ็อกเต็ตสำหรับอินพุตในอัลกอริทึม base64
ฉันควรถือว่า US-ASCII หรือ UTF8? หรือมีคนตัดสินคำถามนี้ไปแล้วบ้าง?
คำตอบ:
RFC 2617สามารถอ่านได้ว่า "ISO-8859-1" หรือ "ไม่ได้กำหนด" ทางเลือกของคุณ. เป็นที่ทราบกันดีว่าเซิร์ฟเวอร์จำนวนมากใช้ ISO-8859-1 (ชอบหรือไม่) และจะล้มเหลวเมื่อคุณส่งอย่างอื่น ดังนั้นทางเลือกเดียวที่ปลอดภัยคือการยึดติดกับ ASCII
สำหรับข้อมูลเพิ่มเติมและข้อเสนอในการแก้ไขสถานการณ์โปรดดูแบบร่าง"An Encoding Parameter for HTTP Basic Authentication" (ซึ่งเป็นพื้นฐานสำหรับ RFC 7617)
ตั้งแต่ปี 2015 มีRFC 7617ซึ่งล้าสมัย RFC 2617 ตรงกันข้ามกับ RFC รุ่นเก่า RFC ใหม่กำหนดการเข้ารหัสอักขระอย่างชัดเจนเพื่อใช้สำหรับชื่อผู้ใช้และรหัสผ่าน
charset="UTF-8"
ในการท้าทายเช่นนี้WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
เวอร์ชันสมบูรณ์:
อ่านข้อมูลจำเพาะ หากมีรายละเอียดเพิ่มเติมเช่นขั้นตอนการเข้ารหัสที่แน่นอนและรายการจุดรหัส Unicode ที่ควรได้รับการสนับสนุน
ในปี 2018 เบราว์เซอร์สมัยใหม่มักจะใช้ค่าเริ่มต้นเป็น UTF-8 หากผู้ใช้ป้อนอักขระที่ไม่ใช่ ASCII สำหรับชื่อผู้ใช้หรือรหัสผ่าน (แม้ว่าเซิร์ฟเวอร์จะไม่ใช้charset
พารามิเตอร์ก็ตาม)
ดินแดนพารามิเตอร์ยังคงสนับสนุนเฉพาะอักขระ ASCII แม้ใน RFC 7617
คำตอบสั้น ๆ : iso-8859-1 เว้นแต่ใช้คำที่เข้ารหัสตาม RFC2047 (MIME)
คำอธิบายอีกต่อไป:
RFC2617 ส่วนที่ 2 (การพิสูจน์ตัวตน HTTP) กำหนดข้อมูลรับรองพื้นฐาน :
basic-credentials = base64-user-pass
base64-user-pass = <base64 encoding of user-pass,
except not limited to 76 char/line>
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
ไม่ควรอ่านข้อมูลจำเพาะโดยไม่อ้างถึง RFC2616 (HTTP 1.1) สำหรับคำจำกัดความใน BNF (เช่นเดียวกับด้านบน):
ข้อกำหนดนี้เป็นสหายกับ HTTP / 1.1 สเปค2 ใช้ส่วนเสริม BNF ส่วน 2.1 ของเอกสารนั้นและอาศัยทั้งที่ไม่ใช่เทอร์มินัลที่กำหนดไว้ในเอกสารนั้นและด้านอื่น ๆ ของข้อกำหนด HTTP / 1.1
RFC2616 ส่วน 2.1กำหนดTEXT (เน้นของฉัน):
กฎ TEXT ใช้สำหรับเนื้อหาฟิลด์อธิบายและค่าที่ไม่ได้ตั้งใจให้ตีความโดยตัวแยกวิเคราะห์ข้อความ คำของ * TEXT อาจมีอักขระจากชุดอักขระอื่นนอกเหนือจาก ISO-8859-1เฉพาะเมื่อเข้ารหัสตามกฎของ RFC 2047
TEXT = <any OCTET except CTLs, but including LWS>
ดังนั้นจึงเป็น iso-8859-1 อย่างแน่นอนเว้นแต่คุณจะตรวจพบการเข้ารหัสอื่น ๆ ตามกฎ RFC2047 (MIME pt.3 ):
// Username: Mike
// Password T€ST
Mike:=?iso-8859-15?q?T€ST?=
ในกรณีนี้เครื่องหมายยูโรในคำว่าจะได้รับการเข้ารหัสเป็น0xA4
ไปตามมาตรฐาน ISO-8859-15 ฉันเข้าใจว่าคุณควรตรวจสอบตัวคั่นคำที่เข้ารหัสเหล่านี้แล้วถอดรหัสคำภายในตามการเข้ารหัสที่ระบุ หากไม่เป็นเช่นนั้นคุณจะคิดว่ารหัสผ่านคือ=?iso-8859-15?q?T¤ST?=
(สังเกตว่า0xA4
จะถูกถอดรหัส¤
เมื่อตีความเป็น iso-8859-1)
นี่คือความเข้าใจของฉันฉันไม่พบการยืนยันที่ชัดเจนมากไปกว่า RFC เหล่านี้ และบางเรื่องก็ดูขัดแย้งกัน ตัวอย่างเช่นหนึ่งใน 4 เป้าหมายที่ระบุไว้ของ RFC2047 (MIME, pt.3) คือการกำหนดใหม่:
รูปแบบของข้อความที่อนุญาตสำหรับ ... ข้อมูลส่วนหัวที่เป็นข้อความในชุดอักขระอื่นที่ไม่ใช่ US-ASCII
แต่แล้ว RFC2616 (HTTP 1.1) กำหนดส่วนหัวโดยใช้กฎ TEXT ซึ่งมีค่าเริ่มต้นเป็น iso-8859-1 หมายความว่าทุกคำในส่วนหัวนี้ควรเป็นคำที่เข้ารหัส (เช่น=?...?=
แบบฟอร์ม) หรือไม่?
เกี่ยวข้องด้วยไม่มีเบราว์เซอร์ปัจจุบันทำเช่นนี้ พวกเขาใช้ utf-8 (Chrome, Opera), iso-8859-1 (Safari), หน้ารหัสระบบ (IE) หรืออย่างอื่น (เช่นบิตที่สำคัญที่สุดจาก utf-8 ในกรณีของ Firefox)
แก้ไข: ฉันเพิ่งรู้ว่าคำตอบนี้มองปัญหามากกว่าจากมุมมองฝั่งเซิร์ฟเวอร์
RFCs กันในกรอบฤดูใบไม้ผลิที่BasicAuthenticationFilter
ระดับเริ่มต้นคือUTF-8
เหตุผลสำหรับตัวเลือกนี้ฉันเชื่อว่า UTF-8 สามารถเข้ารหัสอักขระที่เป็นไปได้ทั้งหมดในขณะที่ ISO-8859-1 (หรือ ASCII) ไม่ใช่ การพยายามใช้ชื่อผู้ใช้ / รหัสผ่านกับอักขระที่ระบบไม่รองรับอาจนำไปสู่พฤติกรรมที่ใช้งานไม่ได้หรือความปลอดภัยลดลง (อาจแย่กว่านั้น)
หากคุณสนใจว่าเบราว์เซอร์ทำอะไรบ้างเมื่อคุณป้อนอักขระที่ไม่ใช่ ascii ที่พรอมต์การเข้าสู่ระบบฉันเพิ่งลองใช้ Firefox
ดูเหมือนว่าจะแปลงเป็น ISO-8859-1 อย่างเฉื่อยชาโดยใช้ไบต์ที่มีนัยสำคัญน้อยที่สุดของค่ายูนิโคดแต่ละค่าเช่น:
User: 豚 (\u8c5a)
Password: 虎 (\u864e)
มีการเข้ารหัสเช่นเดียวกับ:
User: Z (\u005a)
Password: N (\u004e)
0x5a 0x3a 0x4e base64-> WjpO