Công cụ dành cho nhà phát triển · Bộ mã hóa và giải mã Base64
Base64 không phải là mã hóa: tại sao bất kỳ ai cũng có thể đọc được bí mật được mã hóa
· Tại sao nó quan trọng
base64 bảo vệ mã hóa
Base64 không che giấu điều gì: bất kỳ ai có chuỗi đều có thể giải mã nó ngay lập tức mà không cần khóa. Bài đăng này giải thích sự khác biệt giữa mã hóa, mã hóa và băm cũng như những việc cần làm khi bạn tìm thấy bí mật Base64 trong kho lưu trữ.
Giá trị cấu hình trông được xáo trộn và giải mã thành mật khẩu cơ sở dữ liệu — một khám phá cụ thể và tốc độ đảo ngược của nó
Việc tìm Base64 trong tệp cấu hình tạo ra cảm giác an toàn sai lầm. Nhà phát triển phát hiện ra mật khẩu cơ sở dữ liệu xuất hiện dưới dạng một chuỗi được xáo trộn như dGlnZXJfZGF0YWJhc2VfYWRtaW4, cho rằng mật khẩu đó đã được mã hóa và đưa nó vào kho lưu trữ cùng với mã ứng dụng. Vài tuần sau, quá trình đánh giá bảo mật cho thấy bản rõ thực tế: Tiger_database_admin.
Base64 không che giấu gì cả; nó là một mã hóa, không phải mã hóa. Mật khẩu tương tự đã được đảo ngược sẽ trở thành thô ngay lập tức trong trình duyệt, không cần khóa, không tính toán, không chậm trễ. Bài đăng này giải thích lý do tồn tại của mã hóa, về cơ bản nó khác với mã hóa và băm như thế nào cũng như điều gì thực sự xảy ra khi ai đó tìm thấy bí mật Base64 trong lịch sử đã cam kết.
Mã hóa, mã hóa và băm: ba công việc khác nhau — mỗi công việc đảm bảo điều gì và công việc nào cần có khóa
Sự nhầm lẫn nảy sinh vì Base64 trông giống như sự bảo vệ. Con người không thể liếc nhìn dGlnZXJfZGF0YWJhc2VfYWRtaW4 và đọc Tiger_database_admin. Nó có vẻ bị che khuất cho đến khi bạn chạy nó qua bộ giải mã. Sự che giấu ở cấp độ bề mặt đó có vẻ như là sự an toàn, nhưng thực tế không phải vậy. Base64 được thiết kế để giải quyết hoàn toàn một vấn đề khác: di chuyển dữ liệu nhị phân tùy ý qua các kênh chỉ có văn bản. Email, biểu mẫu web cũ hơn và hệ thống giao thức dòng không thể mang byte thô. Base64 chuyển đổi byte thành các ký tự ASCII có thể in được để dữ liệu có thể truyền qua các kênh đó một cách nguyên vẹn.
Sau khi dữ liệu đến, người nhận sẽ giải mã nó trở lại thành byte. Việc mã hóa và giải mã đều đơn giản như nhau; chúng không yêu cầu chìa khóa, không entropy, không thư viện mật mã. Mã hóa, mã hóa và băm phục vụ ba mục đích riêng biệt và đưa ra ba đảm bảo khác nhau. Mã hóa biến đổi dữ liệu thành một cách biểu diễn khác để nó có thể đi qua một kênh cụ thể hoặc được sử dụng trong một ngữ cảnh cụ thể. Mã hóa Base64, URL, biểu diễn hex và thậm chí cả dấu ngoặc kép thoát trong JSON đều là mã hóa. Bất kỳ ai cũng có thể đảo ngược chúng và không yêu cầu khóa bí mật.
Tại sao Base64 lại tồn tại - vận chuyển byte an toàn qua các kênh văn bản, không bao giờ bảo mật
Mục tiêu là khả năng tương thích về định dạng chứ không phải tính bảo mật. Ngược lại, mã hóa yêu cầu khóa chỉ được biết bởi các bên được ủy quyền. Chỉ người có khóa chính xác mới có thể biến bản mã trở lại thành bản rõ. Nếu không có chìa khóa, thông điệp vẫn không rõ ràng ngay cả đối với người đủ tinh vi để tấn công nó. Việc băm được thiết kế theo một chiều: hàm băm mật mã của mật khẩu hoàn toàn không thể đảo ngược được. Nó được sử dụng để xác minh rằng mật khẩu khớp với hàm băm được lưu trữ mà không lưu trữ mật khẩu.
Mật khẩu cơ sở dữ liệu có tên Kubernetes Secret chứa base64: dGlnZXJfZGF0YWJhc2VfYWRtaW4 thực tế không phải là bí mật. Base64 là mã hóa mặc định mà Kubernetes sử dụng để lưu trữ chứ không phải để bảo vệ. Bất kỳ ai có quyền truy cập vào YAML hoặc cơ sở dữ liệu etcd đều có thể giải mã giá trị sau vài giây. Các biến môi trường có khóa API được mã hóa base64 trong tập lệnh khởi động cũng gặp phải vấn đề tương tự. Tiêu đề Xác thực cơ bản gửi Ủy quyền: Basic base64_username:password đến máy chủ có thể được giải mã bởi bất kỳ proxy, công cụ giám sát hoặc trình quan sát mạng nào giữa máy khách và máy chủ.
Ví dụ hoạt động: giải mã chuỗi 'bí mật' trong trình duyệt - dán, giải mã và văn bản gốc, không có máy chủ liên quan
Nếu kênh là HTTP thay vì HTTPS thì mức độ hiển thị thậm chí còn lớn hơn. Base64 trong những bối cảnh này là một con cá trích đỏ: bí mật thực sự đã bị xâm phạm do được lưu trữ hoặc truyền đi ở dạng có thể phục hồi được. Một ví dụ hoạt động làm cho vấn đề trở nên cụ thể. Giả sử khóa API cho dịch vụ bên thứ ba xuất hiện trong tệp cấu hình dưới dạng YXBpa2V5XzEyMzQ1Njc4OTAx. Sao chép chuỗi này vào bộ mã hóa & giải mã Base64 trong trình duyệt của bạn, dán nó vào trường nhập và nhấp vào Giải mã.
Công cụ trả về apikey_1234567890. Điều này xảy ra ngay lập tức, trong trình duyệt của bạn, không cần liên hệ với máy chủ, không cần khóa và không thực hiện xác thực. Toàn bộ hoạt động chỉ mất chưa đầy một giây. Bây giờ, giả sử khóa tương tự này được tìm thấy trong kho lưu trữ GitHub công khai bởi một tác nhân độc hại. Họ giải mã nó một cách dễ dàng như nhau, bằng bất kỳ công cụ nào họ thích và sử dụng nó để truy cập dịch vụ. Cho dù chuỗi vẫn bị che khuất trong kho lưu trữ, di chuyển qua mạng hay xuất hiện trong nhật ký ứng dụng, thì chuỗi đó có thể được tiết lộ bằng một thao tác tầm thường có sẵn trong mọi ngôn ngữ lập trình và trong các công cụ trình duyệt như thế này.
Nơi lỗi này xuất hiện - Bí mật Kubernetes, tệp .env, tiêu đề xác thực cơ bản và tài nguyên ứng dụng di động
Lỗi xuất hiện ở khắp mọi nơi vì Base64 phổ biến đến mức nó liên quan đến sự khó hiểu do khoảng cách gần. Các nhà phát triển xem dữ liệu được mã hóa Base64, suy ra rằng ai đó cho rằng nó quan trọng và để lại bí mật ở dạng đó. Một tệp .env chứa API_KEY=VGhpcyBpcyBub3QgcmVhbGx5IGEgc2VjcmV0 có vẻ an toàn hơn API_KEY=Đây thực sự không phải là một bí mật mặc dù việc giải mã chỉ cần một thao tác. Các ứng dụng di động gói các mã thông báo được mã hóa Base64 trong các tài nguyên mà bất kỳ trình dịch ngược nào cũng có thể trích xuất và giải mã. Bản sao lưu cơ sở dữ liệu chứa mật khẩu được mã hóa Base64 trong các trường nhằm mục đích tìm kiếm chứ không phải được bảo vệ.
Trong mỗi trường hợp, ai đó đã nhầm mã hóa với mã hóa và tạo ra một kho lưu trữ các bí mật văn bản gốc được định dạng theo cách yêu cầu thêm một bước để đọc. Phải làm gì khi bí mật Base64 bị phát hiện tùy thuộc vào ngữ cảnh.
Thay vào đó, phải làm gì - người quản lý bí mật, mã hóa thực sự ở trạng thái lưu trữ và xoay vòng mọi thứ đã được cam kết
Nếu bí mật là mã thông báo, khóa API hoặc mật khẩu và bí mật đó đã được cam kết kiểm soát phiên bản thì hãy coi bí mật đó là bị xâm phạm. Thu hồi nó, tạo một cái mới và cập nhật mọi nơi nó được sử dụng. Cam kết lịch sử là một phần của bản ghi vĩnh viễn của kho lưu trữ ngay cả khi bí mật sau đó bị xóa trong một cam kết mới; bất kỳ ai có quyền truy cập vào lịch sử kho lưu trữ đều có thể tìm thấy nó.
Tìm kiếm các kho lưu trữ cho các giá trị được mã hóa Base64 hiện là một chiến thuật trinh sát tiêu chuẩn, vì vậy việc có thứ gì đó là Base64 không có nghĩa là bí mật. Đối với mọi hoạt động đang diễn ra, đừng bao giờ mã hóa bí mật bằng Base64 và cho rằng chúng được bảo vệ. Sử dụng trình quản lý bí mật lưu trữ các giá trị được mã hóa, kiểm soát quyền truy cập và có thể kiểm tra được. Chỉ lưu trữ tham chiếu hoặc dẫn xuất chứ không phải bí mật trong mã ứng dụng và cấu hình. Mã hóa thực sự ở trạng thái lưu trữ có nghĩa là dữ liệu được mã hóa bằng một khóa được lưu trữ riêng biệt và vô dụng đối với bất kỳ ai không có khóa đó.
Điều này không bao gồm những gì - chọn thuật toán mã hóa hoặc thiết kế quản lý khóa
Cơ sở dữ liệu mã hóa các cột nhạy cảm, trình quản lý bí mật sử dụng mã hóa đường bao bằng khóa trong mô-đun bảo mật phần cứng hoặc trình quản lý mật khẩu lấy khóa mã hóa từ mật khẩu người dùng đều mang lại tính bảo mật thực sự. Mã hóa cấp ứng dụng tại thời điểm bí mật được tạo, trước khi chúng được lưu trữ ở bất kỳ đâu, vẫn mạnh hơn. Việc luân chuyển các bí mật đã bị lộ, ngay cả khi chúng chỉ được mã hóa Base64, sẽ loại bỏ cơ hội sử dụng sai mục đích. Nếu một bí mật nằm trong kho lưu trữ, hãy kiểm tra nhật ký để xem khi nào nó được truy cập và nó được sử dụng để làm gì trong thời gian hiển thị.
Để bảo mật liên tục, hãy sử dụng mã thông báo có thời gian sử dụng ngắn hạn do dịch vụ ủy quyền cấp chứ không phải các bí mật tĩnh được lưu trữ trong cấu hình. Mã thông báo hết hạn sau một giờ sẽ ít có giá trị hơn đối với kẻ tấn công ngay cả khi bị xâm phạm. Bài viết này không đề cập đến việc chọn thuật toán mã hóa, thiết kế quản lý khóa hoặc kiến trúc xác thực. Đó là những câu hỏi kỹ thuật sâu sắc hơn với những tiêu chuẩn và sự đánh đổi riêng. Vấn đề đơn giản hơn: Base64 không phải là một trong những công cụ giải quyết bất kỳ vấn đề nào trong số đó. Nó là một sự chuyển đổi định dạng để vận chuyển và lưu trữ.
Bài học rút ra: coi Base64 là văn bản gốc - cách bộ mã hóa & giải mã Base64 giải quyết vấn đề chỉ bằng một cú nhấp chuột mà không bao giờ có bí mật rời khỏi tab của bạn
Đừng để sự xuất hiện của Base64 trong kho lưu trữ, tệp cấu hình hoặc nhật ký khiến bạn yên tâm rằng dữ liệu được bảo vệ. Bất kỳ công cụ nào có thể đọc văn bản đều có thể giải mã Base64 và thao tác diễn ra tức thời và mang tính xác định. Đọc một chuỗi được mã hóa Base64 dưới dạng văn bản mã hóa là một sự hiểu lầm phổ biến và nó để lại những bí mật thực sự rõ ràng. Các nhà phát triển thường chỉ nhận ra điều này sau khi tìm thấy bí mật Base64 trong quá trình sản xuất hoặc kiểm tra. Một góc nhìn mới mẻ xuất hiện khi một kỹ sư giải mã cục bộ một chuỗi mẫu và thấy bản rõ gốc xuất hiện ngay lập tức.
Công cụ này đưa ra quan điểm không thể tránh khỏi: mã hóa không phải là mã hóa. Khi sự khác biệt đó đã rõ ràng, việc theo dõi sẽ diễn ra tự động. Mọi bí mật Base64 trong cơ sở mã phải được xoay vòng. Mọi nơi bí mật được sử dụng đều phải được cập nhật. Cửa sổ tiếp xúc phải được đánh giá. Trong tương lai, những người quản lý bí mật và mã hóa thực sự phải thay thế vai trò mã hóa. Bộ mã hóa và giải mã Base64 hiển thị chính xác mức độ đảo ngược nhanh chóng và dễ dàng mà bí mật của bạn không bao giờ rời khỏi trình duyệt. Hãy coi sự dễ dàng đó như một tư thế bảo mật thực sự: nếu bạn có thể giải mã nó trong một giây thì bất kỳ ai khác cũng có thể.