ไทย

เครื่องมือสำหรับนักพัฒนา · ตัวเข้ารหัสและตัวถอดรหัส Base64

วิธีสร้างและถอดรหัสส่วนหัวการตรวจสอบสิทธิ์พื้นฐาน HTTP ด้วย Base64

· มันทำงานอย่างไร

base64 ความปลอดภัย

HTTP ส่วนหัวการตรวจสอบสิทธิ์พื้นฐานพร้อมชื่อผู้ใช้: รหัสผ่านที่เข้ารหัส Base64
ภาพประกอบเวกเตอร์ต้นฉบับ ToolAcre

การอนุญาต: ส่วนหัวพื้นฐานเป็นเพียงชื่อผู้ใช้: รหัสผ่านที่ทำงานผ่าน Base64 โพสต์นี้แสดงวิธีการสร้างค่า วิธีถอดรหัสค่าจากบันทึกคำขอ และเหตุใดการเข้ารหัสจึงไม่ซ่อนอะไรเลย

401 ที่ยังคงมีอยู่แม้ว่าข้อมูลประจำตัวจะถูกต้อง - ค่าส่วนหัวที่ถอดรหัสเป็นสตริงที่ผิดอย่างละเอียด

HTTP API ส่งคืน 401 ไม่ได้รับอนุญาตและคาดว่าจะมีการอนุญาต: ส่วนหัวพื้นฐาน ค่าคือคำว่าโครงร่างพื้นฐาน หนึ่งช่องว่าง และสตริง Base64 คำนำหน้าหายไป คำนำหน้าที่เข้ารหัส หรือการขึ้นบรรทัดใหม่โดยไม่มีใครสังเกตเห็นจะเปลี่ยนสิ่งที่เซิร์ฟเวอร์ได้รับ แม้ว่าชื่อผู้ใช้และรหัสผ่านที่มองเห็นจะดูถูกต้องก็ตาม

ถอดรหัสสตริงนั้นและอ่านชื่อผู้ใช้: รหัสผ่าน (โคลอนตามตัวอักษรระหว่างสอง) ชื่อผู้ใช้ไบต์:รหัสผ่านถูกเข้ารหัส UTF-8 จากนั้นเข้ารหัส Base64 เพื่อสร้างค่าส่วนหัว หากข้อมูลประจำตัวคือ admin:s3cret, UTF-8 ไบต์คือ 0x61 0x64 0x6D 0x69 0x6E 0x3A 0x73 0x33 0x63 0x72 0x65 0x74 (ASCII ตัวอักษรบวกโคลอน) การเข้ารหัส Base64 จะสร้าง YWRtaW46czNjcmV0 และส่วนหัวคือการอนุญาต: Basic YWRtaW46czNjcmV0

สูตรอาหารจาก RFC 7617: 'user:pass', UTF-8, Base64 — ขั้นตอนที่แน่นอนและบทบาทของโคลอน

นี่เป็นการเสร็จสมบูรณ์ HTTP รูปแบบการตรวจสอบสิทธิ์พื้นฐานที่กำหนดไว้ใน RFC 7617 มันเรียบง่าย ได้มาตรฐาน และไม่มีการรักษาความปลอดภัยด้วยตัวมันเอง ใครก็ตามที่อ่านส่วนหัวสามารถถอดรหัสได้ทันทีเพื่ออ่านรหัสผ่าน นี่คือเหตุผลว่าทำไม HTTPS จึงจำเป็นสำหรับการตรวจสอบสิทธิ์ขั้นพื้นฐาน การเข้ารหัสเป็นข้อกำหนดในการขนส่ง ไม่ใช่คุณลักษณะด้านความปลอดภัย รหัสผ่านเดินทางเป็น UTF-8 ไบต์ เช่นเดียวกับข้อมูลอื่นๆ Base64 เป็นเพียงสัญลักษณ์ที่ใช้ในโปรโตคอล HTTP

หากจำเป็นต้องถอดรหัสส่วนหัว Basic จากบันทึกเครือข่าย กระบวนการจะตรงไปตรงมา: ตัดส่วนที่เหลือของการถอดรหัส Basic, Base64 และคุณมีชื่อผู้ใช้:รหัสผ่าน โคลอนเป็นตัวคั่นระหว่างชื่อผู้ใช้และรหัสผ่าน RFC 7617 ระบุข้อมูลรับรองเป็น user-id : รหัสผ่าน และโคลอนแรกคือตัวคั่น หากรหัสผ่านมีเครื่องหมายทวิภาค ทวิภาคที่สองจะเป็นเพียงอักขระอื่นในรหัสผ่าน ลำไส้ใหญ่มีโครงสร้างเพราะผู้รับต้องการขอบเขตที่ชัดเจน ค้นหาโคลอนแรกหลังจากการถอดรหัส ทุกอย่างก่อนที่จะระบุผู้ใช้และทุกอย่างหลังจากนั้นคือรหัสผ่าน เครื่องหมายทวิภาคที่หายไปจึงบ่งชี้ว่าคู่ข้อมูลรับรองมีรูปแบบไม่ถูกต้อง ไม่ใช่ปัญหาตัวอักษร Base64

ตัวอย่างการทำงาน: การเข้ารหัส admin:s3cret และการถอดรหัสส่วนหัวจากบันทึก - ทั้งสองทิศทาง รวมถึงข้อผิดพลาดการขึ้นบรรทัดใหม่ต่อท้าย

หากชื่อผู้ใช้คือ admin และรหัสผ่านคือ pass:word ข้อมูลประจำตัวคือ admin:pass:word ซึ่งเข้ารหัสเป็น YWRtaW46cGFzczp3b3Jk เมื่อถอดรหัสจะต้องแยกโคลอนแรกเท่านั้น โดยให้ชื่อผู้ใช้ ผู้ดูแลระบบ และรหัสผ่าน pass:word การแยกโคลอนทุกอันจะทำให้แยกรหัสผ่านไม่ถูกต้อง พารามิเตอร์ชุดอักขระใน RFC 7617 สถานะข้อมูลรับรองมีการเข้ารหัส UTF-8 ซึ่งหมายความว่าอักขระที่ไม่ใช่ ASCII ในชื่อผู้ใช้หรือรหัสผ่านจะถูกแปลงเป็น UTF-8 ไบต์ก่อนการเข้ารหัส Base64

หากชื่อผู้ใช้คือ cafe (เน้นเสียง e) UTF-8 ไบต์คือ 0x63 0x61 0x66 0xC3 0xA9 (สี่ไบต์สำหรับตัวอักษร ASCII บวกสองสำหรับอักขระเน้นเสียง) และข้อมูลรับรองแบบเต็ม cafe:รหัสผ่านมีไบต์สำหรับคาเฟ่ จากนั้นโคลอนไบต์ 0x3A จากนั้นรหัสผ่าน เอาต์พุต Base64 เข้ารหัสไบต์ทั้งหมดอย่างซื่อสัตย์ ตัวถอดรหัสต้องรู้ที่จะตีความไบต์ที่ถอดรหัสเป็นข้อความ UTF-8 ไม่ใช่ภาษาละติน-1

รหัสผ่านที่มีโคลอน ช่องว่าง และ non-ASCII — เหตุใดโคลอนแรกจึงแยก และพารามิเตอร์ชุดอักขระมีไว้เพื่ออะไร

ตัวอย่างการทำงาน: เริ่มต้นด้วย admin:s3cret แปลงเป็น UTF-8 ไบต์: a=0x61, d=0x64, m=0x6D, i=0x69, n=0x6E, :=0x3A, s=0x73, 3=0x33, c=0x63, r=0x72, e=0x65, t=0x74 ในรูปทศนิยม: (97, 100, 109, 105, 110, 58, 115, 51, 99, 114, 101, 116) Base64 เข้ารหัส 12 bytes เหล่านี้: จัดกลุ่มออกเป็นสี่กลุ่ม กลุ่มละสามกลุ่ม (สร้างสี่กลุ่มด้วยอักขระ Base64 สี่ตัว)

ค่าที่เข้ารหัสคือ YWRtaW46czNjcmV0 ส่วนหัวของการอนุญาตคือการอนุญาต: Basic YWRtaW46czNjcmV0 ด้านรหัสผ่านสามารถมีโคลอนอื่นได้โดยไม่ต้องย้ายขอบเขตแรกนั้น การเว้นวรรคและข้อความที่ไม่ใช่ ASCII จะยังคงอยู่เมื่อเพื่อนทั้งสองเห็นด้วยกับการเข้ารหัสข้อความ ToolAcre สามารถตรวจสอบ UTF-8 ไบต์ที่ปล่อยออกมาได้ แต่เซิร์ฟเวอร์รุ่นเก่าที่คาดหวังชุดอักขระที่แตกต่างกันยังคงเป็นปัญหาการทำงานร่วมกันนอกการแปลง Base64

เหตุใดจึงไม่ปลอดภัยหากไม่มี TLS — การถอดรหัสจะแสดงรหัสผ่านแก่ใครก็ตามที่เห็นส่วนหัว

หากต้องการถอดรหัสส่วนหัวที่ได้รับ ให้ตัด Basic, Base64 ถอดรหัส YWRtaW46czNjcmV0 เพื่อรับไบต์กลับ แปลเป็นข้อความ UTF-8 เพื่อรับ admin:s3cret แยกที่โคลอนแรกเพื่อแยกชื่อผู้ใช้และรหัสผ่าน ข้อผิดพลาดทั่วไปคือการต่อท้ายบรรทัดใหม่จาก echo ถ้ารัน echo admin:s3cret | base64 ใน Unix เชลล์ echo เพิ่มขึ้นบรรทัดใหม่ตามค่าเริ่มต้น ดังนั้นเข้ารหัส admin:s3cret ด้วยการขึ้นบรรทัดใหม่ (13 bytes แทน 12)

เอาต์พุต Base64 แตกต่าง: YWRtaW46czNjcmV0Cg== (ช่องว่างภายในและอักขระพิเศษ) ส่วนหัวการอนุญาตที่มีค่านี้จะล้มเหลวเนื่องจากรหัสผ่านมีอักขระขึ้นบรรทัดใหม่ แก้ไขคือใช้ echo -n หรือไพพ์ผ่าน printf หรือเครื่องมือที่ไม่ต่อท้ายบรรทัดใหม่ ตัวเข้ารหัสและตัวถอดรหัส Base64 หลีกเลี่ยงสิ่งนี้: เข้ารหัสสิ่งที่คุณวางทุกประการ ไม่มีการขึ้นบรรทัดใหม่ที่ซ่อนอยู่ TLS เปลี่ยนภัยคุกคามการขนส่ง ไม่ใช่รูปแบบข้อมูลรับรอง ภายในการเชื่อมต่อที่ได้รับการป้องกัน ส่วนหัวจะถูกเข้ารหัสพร้อมกับคำขอที่เหลือ เมื่อซอฟต์แวร์บันทึกหรือแสดงค่าดังกล่าว ค่า Base64 จะเปิดเผยข้อมูลประจำตัวที่นำมาใช้ซ้ำได้อีกครั้งแก่ใครก็ตามที่สามารถถอดรหัสได้ การแก้ไขยังคงมีความสำคัญในทุกจุดสังเกต

ข้อผิดพลาดทั่วไป — การขึ้นบรรทัดใหม่จาก echo ไม่มีคำนำหน้า 'Basic ' และการเข้ารหัสค่าสองครั้ง

ข้อผิดพลาดอื่นไม่มีคำนำหน้าพื้นฐาน ค่าส่วนหัวของการอนุญาตไม่ถูกต้อง Base64 เพียงอย่างเดียว เป็นชื่อโครงการ (พื้นฐานหรือผู้ถือหรืออื่น ๆ ) ตามด้วยช่องว่างแล้วหนังสือรับรอง บางระบบล้มเหลวในการจดจำ YWRtaW46czNjcmV0 เป็นหนังสือรับรอง แต่ประสบความสำเร็จกับ Basic YWRtaW46czNjcmV0 หากทำการดีบัก 401 ให้ตรวจสอบว่าเซิร์ฟเวอร์แยกวิเคราะห์ส่วนหัวการอนุญาตอย่างถูกต้องหรือไม่

Scheme ไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ในมาตรฐาน HTTP แต่การใช้งานจำนวนมากคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ตรวจสอบเอกสาร API การเข้ารหัสสองครั้งเป็นอีกโหมดความล้มเหลว หากสตริงเข้ารหัส Base64 ที่เข้ารหัส Base64 ไว้แล้ว เอาต์พุตจะเป็นสตริงอื่น การเข้ารหัส YWRtaW46czNjcmV0 จะสร้าง WVdkbWFXNDZjek5qY3JldA== (แตกต่างกันโดยสิ้นเชิง) บางระบบอาจใช้การเข้ารหัสสองครั้งโดยไม่ตั้งใจ: ครั้งแรกระหว่างการตั้งค่าข้อมูลรับรอง และอีกครั้งเมื่อสร้างส่วนหัว การขึ้นบรรทัดใหม่จากคำสั่งเชลล์นั้นพลาดได้ง่ายเป็นพิเศษ เนื่องจากสามารถเข้ารหัสเป็นส่วนหนึ่งของข้อมูลรับรอง แทนที่จะถูกปฏิเสธเป็นช่องว่างรอบๆ Base64 ส่วนหัวที่ได้จะถอดรหัสเป็นรหัสผ่านอย่างหมดจดด้วยไบต์เพิ่มเติม ทำให้เกิด 401 ที่ดูเหมือนความล้มเหลวในการตรวจสอบสิทธิ์ฝั่งเซิร์ฟเวอร์

สิ่งนี้ไม่ครอบคลุมถึง - รูปแบบ Digest และ Bearer และการแจ้งเตือนข้อมูลประจำตัวของเบราว์เซอร์

ตัวถอดรหัสคาดว่าจะมีชั้นเดียวของ Base64 ดังนั้นการเข้ารหัสสองครั้งจึงทำให้ไม่ตรงกัน นี่คือสาเหตุที่การบันทึกค่าข้อมูลประจำตัวในรูปแบบ Base64 (ไม่ใช่ข้อความธรรมดา) อาจทำให้เกิดความสับสน: หากมีใครถอดรหัสเพียงครั้งเดียว พวกเขาจะเห็นชื่อผู้ใช้และรหัสผ่าน หากทาสองครั้งจะพบว่ามีความสับสน การตรวจสอบสิทธิ์แบบแยกส่วน (RFC 7616) และการตรวจสอบสิทธิ์แบบผู้ถือ (สำหรับโทเค็น OAuth) ใช้รูปแบบที่แตกต่างกัน โดยแต่ละแบบมีรูปแบบข้อมูลประจำตัวที่แตกต่างกัน

Digest ต้องการให้เซิร์ฟเวอร์ส่ง nonce ไคลเอนต์เพื่อคำนวณแฮช และส่วนหัวเพื่อรวมแฮชบวกชื่อผู้ใช้ ไม่ใช่รหัสผ่าน โดยทั่วไปแล้ว Bearer จะเป็น JSON Web Token (JWT) ซึ่งเข้ารหัส Base64url แต่ไม่ได้นำหน้าด้วยชื่อผู้ใช้ การตรวจสอบสิทธิ์ขั้นพื้นฐานนั้นง่ายกว่าทั้งสองอย่าง แต่ไม่ปลอดภัยโดยสิ้นเชิงหากไม่มี TLS เนื่องจากข้อมูลประจำตัวสามารถอ่านได้ในส่วนหัว Digest และ Bearer ใช้ฟิลด์ส่วนหัว Authorization เดียวกัน แต่กำหนดความหมายที่แตกต่างไปจากเดิมอย่างสิ้นเชิงให้กับค่าของพวกเขา ข้อความรับรองเบราว์เซอร์เพิ่มส่วนต่อประสานผู้ใช้และพฤติกรรมการแคชที่ด้านบนของพื้นฐาน บทความนี้หยุดที่การสร้างและตรวจสอบเพย์โหลดข้อมูลประจำตัวพื้นฐาน แทนที่จะเปรียบเทียบระบบการตรวจสอบความถูกต้องเหล่านั้น

ประเด็นสำคัญ: การรับรองความถูกต้องขั้นพื้นฐานคือ Base64 ไม่ใช่การป้องกัน — ตัวเข้ารหัสและตัวถอดรหัส Base64 ช่วยให้คุณตรวจสอบค่าส่วนหัวในเครื่องโดยไม่ต้องส่งข้อมูลรับรองไปที่ใดเลย

หาก API รองรับรูปแบบการตรวจสอบสิทธิ์หลายรูปแบบ ให้เลือกความปลอดภัยสูงสุดที่มีอยู่ ตัวเข้ารหัสและตัวถอดรหัส Base64 สามารถช่วยแก้ไขข้อบกพร่องการตรวจสอบสิทธิ์พื้นฐานล้มเหลว: วางสตริงข้อมูลรับรอง (ชื่อผู้ใช้และโคลอนและรหัสผ่าน) และเครื่องมือจะสร้างค่า Base64 ทันที เปรียบเทียบผลลัพธ์กับการส่งส่วนหัว และมองเห็นข้อมูลที่ไม่ตรงกันได้ ในทางกลับกัน ให้วางค่าส่วนหัวจากบันทึกเครือข่าย ตัดคำนำหน้าพื้นฐาน ถอดรหัสเพื่อดูว่าเซิร์ฟเวอร์เห็นอะไร

สำหรับการเรียนรู้ ให้วาง admin:s3cret และสังเกตผลลัพธ์ จากนั้นแก้ไขรหัสผ่านเพื่อดูว่า Base64 เปลี่ยนแปลงไปอย่างไร การทำความเข้าใจว่าการสร้างส่วนหัวให้ความกระจ่างว่าทำไมการถอดรหัสจึงต้องรู้รูปแบบ RFC และเหตุใดโคลอนจึงเป็นองค์ประกอบโครงสร้าง ไม่ใช่ Base64 เช็คในเครื่องควรใช้ข้อมูลรับรองที่ประดิษฐ์ขึ้น ไม่ใช่รหัสผ่านจริงที่คัดลอกมาจากการใช้งานจริง เข้ารหัสคู่ ย้ายเอาต์พุตกลับเข้าไปในแผงอินพุต และถอดรหัส เครื่องหมายวรรคตอนและอักขระต่อท้ายที่ตรงกันจะพิสูจน์การแสดงแบบไปกลับก่อนที่ส่วนหัวจะถูกส่งไปที่ใดก็ได้