Công cụ dành cho nhà phát triển · Bộ mã hóa và giải mã Base64
Base64 so với base64url: tại sao bộ giải mã tiêu chuẩn từ chối - và _
· Cách thức hoạt động
base64 mã hóa developer-workflow
base64url hoán đổi + và / cho - và _ để đầu ra có thể di chuyển trong URL và tên tệp mà không cần thoát. Bài đăng này giải thích hai bảng chữ cái, cách chuyển đổi giữa chúng và tại sao phần đệm cũng thường bị bỏ đi.
Mã thông báo giải mã mọi nơi ngoại trừ mã của bạn — lỗi ký tự không hợp lệ do một - hoặc _ gây ra
Phân đoạn JWT không giải mã được trong bộ giải mã Base64 tiêu chuẩn với dấu gạch ngang đặt tên lỗi ký tự không hợp lệ. Nhưng về mặt trực quan, không có dấu gạch ngang nào xuất hiện. Hãy nhìn lại - đúng vậy. Phiên bản base64url sử dụng - trong đó Base64 tiêu chuẩn sử dụng + và _ trong đó sử dụng /. Nhiều bộ giải mã chỉ chấp nhận một bảng chữ cái và mã thông báo được mã hóa để đảm bảo an toàn URL sẽ bị từ chối bởi mã mong đợi RFC 4648 Base64 tiêu chuẩn.
Hai bảng chữ cái tương đương nhau; chuyển đổi giữa chúng là thay thế ký tự cơ học. Vấn đề phát sinh vì + và / có ý nghĩa trong URL. Dấu cộng biểu thị khoảng trống trong dữ liệu biểu mẫu ứng dụng/x-www-form-urlencoded. Dấu gạch chéo lên là dấu phân cách đường dẫn trong URL. Nếu bạn nhúng Base64 trực tiếp vào tham số truy vấn URL mà không mã hóa phần trăm + và bộ giải mã /, có thể hiểu sai chúng.
Tại sao + và / là một vấn đề trong URL và tên tệp - ý nghĩa dành riêng của / trong đường dẫn và + dưới dạng khoảng trắng trong dữ liệu biểu mẫu
A + có thể được đọc dưới dạng khoảng trắng trước khi đến bộ giải mã. A / có thể phân chia giá trị tham số ở sai vị trí. RFC 4648 phần 5 xác định bảng chữ cái base64url để loại bỏ sự mơ hồ: sử dụng - thay vì + và _ thay vì /, để đầu ra an toàn trong URL và tên tệp. Hai bảng chữ cái giống hệt nhau ngoại trừ hai ký tự.
Base64 tiêu chuẩn sử dụng các ký tự ở vị trí 62 và 63: A–Z (0–25), a–z (26–51), 0–9 (52–61), + (62), / (63). base64url sử dụng A–Z (0–25), a–z (26–51), 0–9 (52–61), - (62), _ (63). Mọi thứ khác—tập hợp lại bit, quy tắc đệm, ánh xạ bit tới chỉ mục—đều giống nhau. Chuỗi chỉ mục cho Base64 tiêu chuẩn sẽ tạo ra chuỗi chỉ mục cho base64url; chỉ ký tự ở vị trí 62 và 63 sẽ khác nhau.
Bảng chữ cái base64url từ RFC 4648 phần 5 — hai ký tự được thay thế và tại sao không có gì khác thay đổi
Nếu đầu vào không chứa chỉ số 62 hoặc 63 (không có + hoặc / trong tiêu chuẩn, không - hoặc _ trong base64url), cả hai bảng chữ cái đều tạo ra đầu ra giống hệt nhau. Việc chuyển đổi Base64 tiêu chuẩn sang base64url rất đơn giản để tìm và thay thế: hoán đổi + cho - và / cho _. Giải mã chuỗi base64url trong Base64 tiêu chuẩn yêu cầu đảo ngược: hoán đổi - cho + và _ cho /.
Chuyển đổi là đối xứng và luôn hợp lệ. Nếu bạn gặp phải mã thông báo không giải mã được với lỗi đặt tên ký tự không hợp lệ - hoặc _, hãy kiểm tra xem bộ giải mã có chấp nhận base64url hay không. Nếu không, hãy áp dụng thay thế ký tự và nếu đầu vào được định dạng đúng, việc giải mã sẽ thành công. Hãy xem xét tiêu đề JWT {"alg":HS256","typ":JWT"} được mã hóa dưới dạng base64url. UTF-8 byte tiêu chuẩn trải qua quá trình tập hợp lại bit: ba byte trở thành bốn chỉ số, được tra cứu trong bảng chữ cái base64url. ToolAcre hiển thị phần đệm dưới dạng lựa chọn bộ mã hóa thay vì buộc nó vào nút chuyển đổi bảng chữ cái. Sự tách biệt đó là bằng chứng hữu ích: đầu ra an toàn URL có thể được đệm hoặc không được đệm, trong khi bộ giải mã chuẩn hóa một trong hai dạng trước khi gọi trình duyệt nguyên thủy. Bảng chữ cái và phần đệm là các quy ước có liên quan, không phải là một công tắc.
Phần đệm trong base64url là tùy chọn theo quy ước - tại sao JWT bỏ qua = và cách bộ giải mã có thể khôi phục nó từ độ dài
Khi chỉ mục là 62, ký tự đầu ra là -; khi 63, đầu ra là _. Các byte giống hệt nhau thông qua bảng chữ cái tiêu chuẩn sẽ tạo ra + tại chỉ mục 62 và / tại chỉ mục 63. Việc chuyển đổi kết quả base64url sang chuẩn là thao tác từng ký tự: quét - và thay thế bằng +, quét _ và thay thế bằng /, sau đó giải mã như bình thường.
Số byte bạn khôi phục giống hệt nhau vì các chỉ số giống hệt nhau; chỉ có các biểu tượng là khác nhau. Phần đệm trong base64url là tùy chọn theo quy ước, mặc dù tiêu chuẩn cho phép điều đó. JWT được cấu trúc thành ba phân đoạn base64url được nối bằng dấu chấm; mỗi phân đoạn sử dụng phần đệm nếu được yêu cầu, nhưng nhiều quá trình triển khai bỏ qua phần đệm đó và dựa vào thực tế là ứng dụng tiêu thụ biết độ dài byte dự kiến.
Ví dụ đã hoạt động: chuyển đổi phân đoạn tiêu đề JWT thành Base64 tiêu chuẩn — thay thế các ký tự, thêm phần đệm, giải mã thành JSON
Bộ giải mã có thể khôi phục phần đệm bị thiếu bằng cách chia độ dài chuỗi cho 4, tính toán phần còn lại, thêm 0, 1 hoặc 2 dấu bằng. Nếu độ dài chuỗi không phải là bội số của bốn thì thiếu phần đệm là điều hiển nhiên. Nếu độ dài là bội số của 4 thì chuỗi đã được đệm rồi loại bỏ phần đệm hoặc đầu vào đã là bội số của 4 byte (kết thúc bằng 3 byte ở khối cuối cùng, không cần đệm).
Việc ghép các phân đoạn base64url đòi hỏi phải chú ý đến phần đệm. Nếu ba phân đoạn, mỗi phân đoạn kết thúc bằng =, thì việc ghép nối trực tiếp sẽ tạo ra các chuỗi như AAAA=BBBB=CCCC=, trong đó phần đệm ở giữa giờ đây là các ký tự đi lạc, không phải là điểm đánh dấu kết thúc. Đây là lý do tại sao JWT bỏ qua phần đệm trong mỗi phân đoạn: cấu trúc ba phân đoạn là rõ ràng, do đó quá trình giải mã được tiến hành độc lập trên từng phần và việc đệm vào giữa chuỗi nối là không cần thiết và sẽ phá vỡ quá trình phân tích cú pháp.
Các lỗi phổ biến - trộn các bảng chữ cái trong một chuỗi hoặc tiêu chuẩn mã hóa phần trăm Base64 thay vì sử dụng base64url
Nếu xây dựng tải trọng nhiều phân đoạn, hãy quyết định quy ước đệm ngay từ đầu: bao gồm trong mỗi phân đoạn và không bao giờ nối trực tiếp hoặc bỏ qua và chỉ khôi phục từ độ dài khi giải mã. RFC 4648 tiêu chuẩn có thẩm quyền đối với cả hai bảng chữ cái. Phần 4 chỉ định tiêu chuẩn Base64; phần 5 chỉ định base64url. Mỗi bộ giải mã phù hợp phải nêu rõ bảng chữ cái nào nó chấp nhận.
Mã chấp nhận base64url nhưng không chấp nhận Base64 tiêu chuẩn (hoặc ngược lại) chỉ đang triển khai tập hợp con. Bảng chữ cái base64url tồn tại để tương thích với các ràng buộc URL và tên tệp; nó không phải là cải tiến hay thay thế, chỉ là biến thể cho bối cảnh cụ thể. Khi bạn tạo API hoặc định dạng mã thông báo, hãy chọn một bảng chữ cái và ghi lại bảng chữ cái đó. Một lỗi phổ biến là tiêu chuẩn mã hóa phần trăm Base64 thay vì sử dụng base64url. Việc thực hiện cũng giải thích ranh giới bài viết. Nó bình thường hóa dấu gạch nối và dấu gạch dưới trước khi giải mã, nhưng nó không xác minh chữ ký mã thông báo hoặc giải thích các xác nhận quyền sở hữu. Việc chuyển đổi phân đoạn JWT thành byte có thể tiết lộ JSON; không thể xác định ai đã ban hành JSON đó hoặc liệu có ai đã thay đổi nó hay không.
Điều này không bao gồm những gì — xác minh JWT chữ ký, base32 và các mã hóa RFC 4648 khác
%2B là mã phần trăm cho +; %2F là mã phần trăm cho /. Mã hóa phần trăm biến TWFu thành TWFu không thay đổi (không có ký tự đặc biệt) nhưng TE9S+g== thành TE9S%2Bg%3D%3D (quá nhiều ký tự để xử lý). Giải pháp đúng là sử dụng base64url, đã tạo ra đầu ra URL-safe. Base64 mã hóa phần trăm là không cần thiết và lãng phí. Sử dụng đúng bảng chữ cái cho ngữ cảnh. Bộ mã hóa và giải mã Base64 tự động chấp nhận cả hai bảng chữ cái.
Nếu bạn dán chuỗi chứa -, nó sẽ coi chuỗi đó là base64url; nếu dán chuỗi chứa +, nó sẽ coi chuỗi đó là Base64 tiêu chuẩn. Công cụ cũng chấp nhận các URL và coi chúng là đầu vào an toàn URL. Do đó, kiểm tra thực tế có hai kết quả độc lập: chuyến đi khứ hồi byte và biểu diễn được chọn phù hợp với kênh của nó. Vượt qua cái đầu tiên cho biết sự chuyển đổi có thể đảo ngược. Việc chuyển tiếp thứ hai cho biết dấu câu và phần đệm sẽ không được viết lại bởi URL, tên tệp, cookie hoặc giao thức mang nó.
Bài học rút ra: hai bảng chữ cái, bố cục một bit - cách bộ mã hóa & giải mã Base64 xử lý bảng chữ cái tiêu chuẩn trong trình duyệt và nơi trang công cụ của nó nêu rõ những gì nó chấp nhận
Khi giải mã phân đoạn JWT hoặc mã thông báo URL an toàn, bạn có thể dán trực tiếp mà không cần chuyển đổi và công cụ sẽ xác định bảng chữ cái từ ngữ cảnh. Việc gỡ lỗi giải mã không thành công trở nên đơn giản: dán mã thông báo, xem liệu công cụ có chấp nhận nó không và nếu không, hãy hoán đổi ký tự theo cách thủ công và thử lại.
Bản thân sự thay thế là một dòng mã, nhưng việc giải mã không thành công cũng có thể xuất phát từ độ dài không hợp lý, phần đệm đặt sai vị trí, lỗi hoặc đầu vào không phải Base64. Công cụ này tự động chuẩn hóa cả hai bảng chữ cái, do đó việc chấp nhận chỉ xác nhận rằng byte có thể được phục hồi. Tải trọng JWT đã được giải mã vẫn là xác nhận quyền sở hữu chưa được ký cho đến khi một trình xác minh riêng biệt kiểm tra chữ ký và thuật toán dự kiến của nó.