Tiếng Việt

Công cụ dành cho nhà phát triển · Bộ mã hóa và giải mã Base64

RFC 4648 đã giải thích: tiêu chuẩn xác định Base64, base32 và base16

· Lý lịch

base64 mã hóa

RFC 4648 họ bảng chữ cái: base64, base64url, base32, base32hex, base16
Hình minh họa vector ToolAcre gốc

RFC 4648 là tài liệu ngắn gọn, dễ đọc đằng sau mỗi lần triển khai Base64. Bài đăng này trình bày những gì nó chỉ định, những gì nó cố tình để ngỏ và lý do tại sao việc triển khai vẫn khác nhau.

Hai thư viện, hai câu trả lời cho cùng một chuỗi — một câu đố về khả năng tương tác thực sự mà chỉ có tiêu chuẩn mới giải quyết được

Hai thư viện JavaScript có thể trả về Base64 khác nhau cho cùng một chuỗi, mỗi thư viện đều xác nhận tính chính xác. RFC 4648 là tài liệu dài 12 trang có thể đọc được để giải quyết những bất đồng như vậy nhưng việc triển khai vẫn khác nhau do RFC cố tình để lại một số quyết định nhất định cho ứng dụng. Bài viết này trình bày những gì RFC 4648 chỉ định, những gì nó cố ý ủy quyền cho người gọi và tại sao việc đọc tiêu chuẩn một lần lại giải quyết được hầu hết các vấn đề về khả năng tương tác thực sự. Công cụ mã hóa và giải mã Base64 bao gồm RFC 4648 vectơ kiểm tra để bạn có thể xác minh việc triển khai dựa trên các ví dụ chính thức.

RFC 4648 đã thay thế và hợp nhất một số tài liệu trước đó: Base64 từ MIME (RFC 2045), Base64 từ Thư được tăng cường quyền riêng tư (RFC 1421), base32 từ S/MIME (RFC 2630) và base16 từ nhiều nguồn khác nhau. Việc hợp nhất là cần thiết vì MIME và PEM mỗi bảng chữ cái và quy tắc riêng, đồng thời việc ngắt dòng của MIME xung đột với các khối cột 64 của PEM. RFC 4648 xác định năm nhóm mã hóa ở một nơi: base64, base64url, base32, base32hex và base16, mỗi nhóm có bảng chữ cái, quy tắc đệm và vectơ kiểm tra mẫu riêng. Bảng chữ cái base64 là A-Z, a-z, 0-9, cộng và gạch chéo, theo thứ tự đó.

Các vectơ triển khai và kiểm tra thiết lập những gì - bảng chữ cái, phần đệm và khoảng trắng tiêu chuẩn và URL an toàn

Mỗi ký tự đại diện cho 6 bits; ba byte đầu vào (24 bits) ánh xạ tới bốn ký tự đầu ra. Bảng chữ cái không phải là tùy ý: nó tránh các ký tự khác nhau giữa EBCDIC và ASCII, tránh các ký tự điều khiển, dấu ngoặc kép và dấu gạch chéo ngược cần thoát trong chuỗi ký tự C. Biến thể base64url thay thế dấu cộng bằng dấu gạch ngang và dấu gạch chéo bằng dấu gạch dưới để tránh các ký tự dành riêng trong URL và tên tệp. Cả hai biến thể đều có giá trị như nhau; RFC 4648 phần 2 chỉ định base64, phần 5 chỉ định base64url và ứng dụng phải nêu rõ nó sử dụng base64 nào.

Phần đệm với các ký tự bằng sẽ đưa kết quả đầu ra thành bội số của bốn ký tự. Nếu đầu vào là 1 byte (8 bits), thì đầu ra là hai ký tự cộng với hai dấu bằng. Nếu đầu vào là 2 bytes (16 bits), đầu ra sẽ có ba ký tự cộng với một dấu bằng. Nếu dữ liệu đầu vào là bội số của 3 bytes thì không cần đệm. Một số ứng dụng bỏ qua phần đệm hoặc cho phép thiếu phần đệm khi giải mã; RFC 4648 phần 3.2 xác định mã hóa chuẩn là luôn được đệm nhưng phần 3.3 lưu ý rằng bộ giải mã có thể chấp nhận phần đệm bị thiếu để tương thích.

Các bảng chữ cái mà công cụ này triển khai — Base64 và Base64url tiêu chuẩn; các căn cứ khác vẫn nằm ngoài phạm vi của nó

Sự khác biệt về phần đệm là lý do tại sao việc triển khai không đồng ý: một bộ giải mã nghiêm ngặt sẽ loại bỏ các giá trị bằng bị thiếu, trong khi một bộ giải mã khoan dung chấp nhận nó. RFC 4648 nói rõ ràng: ký tự đệm bằng thường được mã hóa phần trăm khi sử dụng trong URL, vì vậy nếu đầu ra base64url được sử dụng trực tiếp trong tham số URL thì phần đệm không bắt buộc và nên được bỏ qua. Câu này là một lý do khiến URL-chế độ an toàn và thiếu phần đệm thường được ghép nối với nhau, mặc dù chúng là những lựa chọn độc lập. Phần 5 (base64url) không cấm đệm; nó chỉ ghi lại thực tiễn thông thường.

Người gọi chọn base64url phải quyết định xem hệ thống nhận có cần đệm hay không. Các ký tự không phải bảng chữ cái trong đầu vào được xử lý khác nhau bởi các bộ giải mã khác nhau. RFC 4648 phần 3.1 nêu rõ: Việc triển khai MUST từ chối mã hóa nếu nó chứa các ký tự bên ngoài bảng chữ cái cơ sở. Tuy nhiên, phần 3.3 lưu ý rằng MIME Base64 (RFC 2045) cho phép ngắt dòng để gói 76 ký tự và bộ giải mã cho MIME phải bỏ qua khoảng trắng. RFC phân biệt giữa giải mã nghiêm ngặt (từ chối tất cả không phải bảng chữ cái) và giải mã tương thích MIME (bỏ qua khoảng trắng, từ chối các ký tự khác).

Phần đệm, ký tự không phải bảng chữ cái và mã hóa chuẩn - những phần giải thích hầu hết những bất đồng về bộ giải mã

Ứng dụng phải chọn quy tắc nào để tuân theo; tiêu chuẩn xác định cả hai. Base32 sử dụng A-Z và 2-7 (tổng cộng 32 ký tự), mã hóa năm byte đầu vào (40 bits) thành tám ký tự đầu ra. Base32hex thay thế 0-9 và a-v cho các ký tự chữ cái, hữu ích trong bối cảnh ưu tiên chữ cái viết thường.

Base16 là hệ thập lục phân: 0-9 và a-f. Base32 và base32hex có quy tắc đệm riêng trong các phần 6 và 7, đồng thời RFC cung cấp các vectơ kiểm tra riêng cho từng bảng chữ cái. Hầu hết các nhà phát triển chỉ cần base64 và base64url; base32, base32hex và base16 được bao gồm trong RFC để đảm bảo tính đầy đủ và cho các ứng dụng như mã hóa TOTP bí mật (RFC 4226) và DNS.

Các lựa chọn ứng dụng hiển thị trong quá trình triển khai này - ngắt dòng, giải mã văn bản nghiêm ngặt và xử lý lỗi

Các vectơ kiểm tra trong RFC 4648 là cơ sở thực tế để kiểm tra việc triển khai. Mã hóa các chuỗi f, fo, foo, foob, fooba và foobar tạo ra đầu ra base64 cụ thể: Zg==, Zm8=, Zm9v, Zm9vYg==, Zm9vYmE= và Zm9vYmFy. Việc triển khai tạo ra kết quả đầu ra khác nhau cho các chuỗi này là không chính xác. RFC cung cấp các vectơ thử nghiệm tương đương cho base32, base32hex và base16. Công cụ mã hóa & giải mã Base64 bao gồm các vectơ này để bạn có thể xác minh đầu ra của nó so với tiêu chuẩn. Gói dòng là mối quan tâm MIME chứ không phải mối quan tâm của base64.

RFC 2045 chỉ định 76 dòng ký tự; RFC 4648 phần 3.1 lưu ý điều này trong ngữ cảnh của MIME nhưng bản thân nó không coi đó là yêu cầu của base64. Một số ứng dụng bao gồm 64 ký tự (tiêu chuẩn PEM ban đầu); những người khác không quấn gì cả. Bộ giải mã base64 RFC 4648 nghiêm ngặt chỉ hoạt động trên bảng chữ cái và phần đệm. Bộ giải mã tương thích MIME phải bỏ qua ngắt dòng (CR, LF, CRLF). Ứng dụng sử dụng base64 bên ngoài MIME không nên thêm dấu ngắt dòng trừ khi hệ thống nhận yêu cầu chúng; RFC không xác định việc ngắt dòng như một phần của base64.

Ví dụ hoạt động: vectơ thử nghiệm của chính RFC — mã hóa tiền tố 'foobar' và kiểm tra chúng trong trình duyệt

Xử lý khoảng trắng là một điểm khác của phương sai triển khai. RFC 4648 cho biết bộ giải mã nghiêm ngặt phải từ chối các ký tự không phải bảng chữ cái. MIME-wrapped base64 (RFC 2045 base64) cho phép khoảng trắng để định dạng. Hai tiêu chuẩn thống nhất về byte đầu ra nhưng khác nhau về đầu vào nào hợp lệ. Hầu hết các triển khai JavaScript đều chọn khả năng tương thích MIME và bỏ qua khoảng trắng; quy tắc nghiêm ngặt hiếm khi được sử dụng trong trình duyệt. Bộ mã hóa và giải mã Base64 chấp nhận cả đầu vào chứa khoảng trắng (MIME) và đầu vào nghiêm ngặt, giúp phân biệt rõ ràng. Giải mã Canonical và tha thứ là sự khác biệt lớn cuối cùng.

Quá trình giải mã chuẩn tuân theo phần RFC 4648 3.2: từ chối phần đệm không đúng định dạng, từ chối phần đệm bị thiếu, từ chối các ký tự không phải bảng chữ cái. Giải mã tha thứ, được sử dụng trong các tiêu chuẩn web (thông số HTML gọi nó là tha thứ-base64), thêm các quy tắc: bỏ qua khoảng trắng, chấp nhận phần đệm bị thiếu, cho phép gạch ngang và gạch dưới cộng với dấu gạch chéo tương đương ngay cả trong chế độ base64 tiêu chuẩn. atob() của JavaScript đang tha thứ; bộ giải mã RFC 4648 nghiêm ngặt thì chặt chẽ hơn. Điều đó cũng không sai; chúng phục vụ các bối cảnh khác nhau. Một ứng dụng đọc dữ liệu từ người dùng hoặc từ mạng sẽ biết phía bên kia mong đợi quy tắc nào.

Điều này không bao gồm những gì — chính các tài liệu MIME và PEM cũng như các API dành riêng cho ngôn ngữ

RFC để lại chín lựa chọn cho ứng dụng: bảng chữ cái nào trong năm bảng chữ cái, yêu cầu hay cho phép phần đệm, yêu cầu hay cho phép khoảng trắng, có coi dấu gạch dưới là dấu gạch chéo tương đương hay không, cách báo cáo lỗi, cách xử lý phần cuối của đầu vào, có chấp nhận phần đệm bị thiếu hay không, số byte đầu ra cần phân bổ và cách báo hiệu giới hạn kích thước. Những lựa chọn này giải thích lý do tại sao hai quá trình triển khai RFC 4648 có thể không đồng nhất trên cùng một đầu vào. Đọc RFC một lần; kiểm tra việc triển khai của bạn dựa trên các vectơ thử nghiệm của nó; nêu rõ các tùy chọn mà ứng dụng của bạn sử dụng; kiểm tra khả năng tương tác với thiết bị ngang hàng thực tế chứ không phải giả định.

Việc hiểu RFC 4648 giải quyết hầu hết các tranh chấp Base64 vì sự bất đồng thường không phải về bản thân RFC mà là về các phương án mà mỗi bên đã chọn. RFC đủ ngắn gọn để đọc từ đầu đến cuối trong một giờ. Tiêu chuẩn xác định các bảng chữ cái, cung cấp các vectơ kiểm tra và cảnh báo nơi việc triển khai phải quyết định. Công cụ mã hóa & giải mã Base64 cho phép bạn thử nghiệm các vectơ kiểm tra và xem bảng chữ cái tiêu chuẩn đang hoạt động. Hầu hết việc sử dụng base64 hàng ngày không yêu cầu kiến ​​thức sâu về RFC; nhưng khi gỡ lỗi mã hóa không khớp hoặc tích hợp với API không quen thuộc, việc đọc tiêu chuẩn sẽ loại bỏ phỏng đoán.

Bài học rút ra: đọc tiêu chuẩn một lần — cách bộ mã hóa & giải mã Base64 cung cấp cho bạn một cách nhanh chóng để kiểm tra các vectơ kiểm tra của bảng chữ cái tiêu chuẩn

RFC 4648 là sự hợp nhất của nhiều thập kỷ thực hành mã hóa cơ sở đặc biệt thành một đặc tả có thể đọc được. Nó không xác định khi nào nên sử dụng base64 (MIME, PEM, JWT, URI dữ liệu, v.v. mỗi URI có thông số kỹ thuật riêng); nó định nghĩa base64 là gì. Bằng cách xác định năm họ mã hóa và lưu ý những tùy chọn nào là chuẩn, RFC giúp bạn có thể kiểm tra xem việc triển khai có đúng hay không. Các vectơ kiểm tra chính thức là điểm bắt đầu: nếu quá trình triển khai của bạn mã hóa foobar và tạo ra bất kỳ thứ gì khác ngoài Zm9vYmFy, thì RFC cho biết việc triển khai sai.

Sử dụng quyền đó làm điểm kiểm tra xác minh: mã hóa từng vectơ kiểm tra RFC, so sánh các ký tự chính xác rồi giải mã kết quả để xác nhận rằng byte gốc trả về không thay đổi. Kiểm tra dựa trên trình duyệt này sẽ tách lỗi bảng chữ cái hoặc lỗi đệm khỏi vấn đề ở nơi khác trong tích hợp, trong khi vẫn giữ tiêu chuẩn làm tham chiếu thay vì dựa vào nhãn thư viện.