Công cụ dành cho nhà phát triển · Máy tính hàm băm SHA
Cùng một văn bản, khác nhau SHA-256: Dòng mới, mã hóa và byte ẩn
· Cách thức hoạt động
sha-256 mã hóa text-processing gỡ lỗi
Dòng lệnh nói một điều và trình duyệt nói một điều khác đối với những gì trông giống như cùng một văn bản. Theo dõi các dòng mới, UTF-16 và CRLF giải thích hầu hết mọi trường hợp; bài đăng này cho thấy cách tìm các byte ẩn.
echo nói một hàm băm, công cụ nói một hàm băm khác — sự không khớp hàng ngày và tại sao cả hai đều không sai
Một thiết bị đầu cuối báo cáo một thông báo SHA-256 và một trình duyệt báo cáo một thông báo khác về nội dung có vẻ giống văn bản. Công cụ dòng lệnh không bị hỏng và trình duyệt cũng vậy. Các byte được băm không giống nhau, mặc dù các ký tự hiển thị trông giống hệt nhau. Bài đăng này theo dõi các nguồn phổ biến nhất của các byte ẩn đó và chỉ ra cách tìm chúng bằng trường văn bản và trình xem hex.
Vấn đề gần như không bao giờ nằm ở chính thuật toán SHA-256. SHA-256 mang tính quyết định: các byte giống nhau luôn tạo ra cùng một thông báo và thông báo đó là chính xác. Khi đầu ra khác nhau, các byte sẽ khác nhau. Sự nhầm lẫn nảy sinh vì "cùng một văn bản" không rõ ràng: một người nhìn thấy các ký tự, nhưng hàm băm nhìn thấy byte và bản dịch giữa chúng là nơi ẩn chứa những khác biệt tiềm ẩn.
Dòng mới ở cuối - cách echo nối thêm một byte còn printf thì không và điều đó có tác dụng gì đối với thông báo
Lệnh echo trong shell sẽ thêm ký tự dòng mới (U+000A, byte 0x0A) vào đầu ra của nó. Đây là do thiết kế: quy ước trong Unix rằng các tệp văn bản kết thúc bằng một dòng mới sẽ tạo ra một công việc đơn giản. Khi bạn nhập echo abc vào một thiết bị đầu cuối và chuyển nó sang sha256sum, các byte được tiêu hóa là 61 62 63 0A (ASCII mã cho a, b, c và byte cho dòng mới), không phải 61 62 63. Công cụ ToolAcre sử dụng để tính toán các giá trị băm băm các byte 61 62 63 và tạo ra một kết quả khác.
Lệnh printf không thêm dòng mới trừ khi bạn viết dòng đó vào chuỗi định dạng. printf abc | sha256sum chỉ tính toán tổng hợp các byte 61 62 63, phù hợp với công cụ trình duyệt. Đây là lý do tại sao việc so sánh các giá trị băm thường có nghĩa là chạy printf thay vì echo hoặc chuyển sang sha256sum bằng cờ -z hoặc chỉ định đầu vào thô ở bất kỳ dạng nào mà công cụ của bạn cung cấp. Dòng mới bị ẩn là lý do phổ biến nhất khiến công cụ trình duyệt và công cụ dòng lệnh không đồng ý.
UTF-8 so với UTF-16 — tại sao các ký tự giống nhau lại là các byte khác nhau trong một số shell và trình soạn thảo
UTF-8 và UTF-16 mã hóa các ký tự giống nhau dưới dạng các chuỗi byte khác nhau. Ký tự é (U+00E9, chữ e có dấu cấp tính) mã hóa thành hai UTF-8 byte: 0xC3 0xA9. Trong UTF-16, đó là cách JavaScript thể hiện chuỗi bên trong, cùng một ký tự chiếm hai byte theo một thứ tự khác (tùy thuộc vào độ cuối) hoặc một dạng hoàn toàn khác nếu được tạo từ một ký tự cơ sở và dấu kết hợp. Khi bạn sao chép quán cà phê từ một ứng dụng Windows và dán nó vào công cụ băm của trình duyệt, các byte mà công cụ băm có thể không khớp với những gì mà thiết bị đầu cuối Mac băm, vì hệ thống được mặc định có các dạng mã hóa hoặc chuẩn hóa khác nhau.
Công cụ băm ToolAcre chuyển đổi rõ ràng văn bản thành UTF-8 trước khi băm qua TextEncoding. Đây là cách mã hóa tương tự mà dòng lệnh Unix sử dụng theo mặc định. Mã nguồn trong ứng dụng/dev/src/lib/base64.js hiển thị hàm textToBytes gọi TextEncoding().encode() mới, đảm bảo UTF-8. Nếu một hệ thống khác đang sử dụng UTF-16 hoặc Latin-1 hoặc bất kỳ mã hóa nào khác thì số byte được tạo ra sẽ khác nhau. Công cụ này hiển thị số byte cùng với thông báo, đó là lý do tại sao việc dán quán cà phê và so sánh với hàm băm dòng lệnh sẽ hiển thị số byte khác nhau nếu các mã hóa phân kỳ.
CRLF, BOM và chuẩn hóa — kết thúc dòng, dấu thứ tự byte và các dấu tổng hợp so với phân tách như những khác biệt đầu vào vô hình
CRLF (trả về đầu dòng + nguồn cấp dữ liệu, byte 0x0D 0x0A) là quy ước kết thúc dòng trên Windows; LF (chỉ nguồn cấp dữ liệu dòng, byte 0x0A) là quy ước Unix. Một tệp văn bản trông giống hệt nhau khi được mở trong trình soạn thảo văn bản có thể mang các kết thúc dòng khác nhau và các byte đó là một phần của đầu vào của hàm băm. Một tệp được chỉnh sửa trên Windows và được kiểm tra dựa trên SHA-256 được tính toán trên hệ thống Unix sẽ không khớp nếu một hệ thống đã chuyển đổi phần cuối dòng còn hệ thống kia thì không.
Dấu thứ tự byte (BOM, byte 0xEF 0xBB 0xBF cho UTF-8) là một chuỗi tùy chọn ở đầu tệp báo hiệu mã hóa. Một số biên tập viên thêm nó; một số công cụ loại bỏ nó; một số bỏ qua nó. Nếu một tệp mang BOM và bạn băm nó theo từng byte thì BOM byte là một phần của thông báo. Sau đó, nếu bạn sao chép văn bản hiển thị (mà người xem ẩn BOM) vào một công cụ không thêm BOM thì nội dung tóm tắt sẽ không khớp. Các biểu mẫu chuẩn hóa văn bản (NFD so với NFC đối với dấu trọng âm tổng hợp và phân tách) thêm một lớp khác: cùng một chữ cái có dấu có thể được biểu diễn dưới dạng một ký tự được soạn trước hoặc dưới dạng ký tự cơ sở, theo sau là dấu trọng âm kết hợp và các chuỗi byte sẽ khác nhau.
Ví dụ đã hoạt động - một chuỗi được băm có và không có dòng mới, sau đó ở hai bảng mã, với mỗi chênh lệch byte được hiển thị
Phương pháp chẩn đoán thứ nhất: sử dụng công cụ kết xuất hex hoặc công cụ chuyển đổi trực tuyến để xem chính xác byte mà công cụ của bạn đang hoạt động. Dán văn bản vào bộ mã hóa base64, mã hóa nó và bạn có bản ghi văn bản của byte. Sau đó giải mã base64 trên dòng lệnh bằng base64 -d và chuyển nó thành od -A x -t x1z để xem chuỗi byte hex. Nếu các byte khớp nhau thì thuật toán đúng; nếu không, sự khác biệt sẽ được nhìn thấy.
Phương pháp chẩn đoán hai: sử dụng máy tính băm ToolAcre SHA để băm các đầu vào dài dần, bắt đầu bằng một ký tự đơn. Thêm dòng mới (có nghĩa là nhập Enter vào bên trong hộp văn bản), thêm dấu cách, thêm cùng một văn bản với các chuỗi thoát UTF-16 nếu dữ liệu đầu vào đến từ nguồn không phảiASCII. Xem sự thay đổi tiêu hóa với mỗi lần bổ sung. Số byte được hiển thị cùng với thông báo cho bạn biết công cụ đang băm bao nhiêu byte, điều này thu hẹp đáng kể phạm vi tìm kiếm.
Kiểu chữ Hex và khoảng trắng ở đầu ra — sự khác biệt hoàn toàn chỉ mang tính thẩm mỹ
Biểu diễn thập lục phân của một bản tóm tắt không phân biệt chữ hoa chữ thường. Cả chữ hoa và chữ thường đều biểu thị cùng một byte: A = 10, a = 10. Một số công cụ phát ra chữ hoa, một số công cụ viết thường, một số cho phép. Nếu một bản tóm tắt là chữ thường và một bản tóm tắt khác là chữ hoa thì chúng là cùng một bản tóm tắt. Khoảng trắng trong màn hình thông báo hoàn toàn mang tính thẩm mỹ. Thông báo hiển thị dưới dạng ba78 16bf so với ba7816bf là như nhau; không gian chỉ là một sự lựa chọn định dạng. Sự không khớp do chữ hoa hoặc khoảng trắng gây ra không phải là sự không khớp thực sự.
Sự khác biệt về định dạng có chiều rộng cố định cũng không thể nhìn thấy được ở cấp độ byte. Thông báo hiển thị bằng dấu gạch nối, dấu cách hoặc dấu hai chấm (như ba-78-16-bf) là quy ước định dạng giúp con người dễ đọc hơn chứ không phải thay đổi số byte thực tế. Công cụ ToolAcre luôn phát ra chữ thường không có dấu phân cách, đây là định dạng mà hầu hết các công cụ dòng lệnh in. Nếu bạn đang so sánh với một công cụ phát ra khác nhau, trước tiên hãy chuyển đổi sang cùng một biểu diễn.
Điều này không bao gồm những gì - các tệp băm, trong đó áp dụng các nguyên tắc tương tự nhưng các byte đến từ đĩa chứ không phải trường văn bản
Công cụ tính hàm băm ToolAcre SHA thực hiện chuyển đổi UTF-8 trước khi băm, hiển thị số byte đầu vào và cung cấp dạng đầu ra cơ sở64 và thập lục phân. Tệp nguồn apps/dev/src/lib/hash.js hiển thị hàm hashText gọi digBytes, chuyển bytes.slice().buffer tới crypto.subtle.digest. Nhận xét trong tệp đó ghi lại rõ ràng rằng bước UTF-8 là có chủ ý và lưu ý sự khác biệt giữa các cách mã hóa khác nhau. Việc kiểm tra dữ liệu đầu vào của bạn dựa trên vectơ đã biết (abc băm thành ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ở dạng hex) sẽ xác nhận rằng công cụ trình duyệt đang hoạt động chính xác; bất kỳ sai lệch nào cũng chỉ ra sự khác biệt byte trong đầu vào.
Việc băm tệp tuân theo nguyên tắc tương tự. Các byte trong tệp mới là vấn đề quan trọng: sự khác biệt ở cuối dòng khi bạn xuất từ hệ thống này và nhập sang hệ thống khác có thể thay đổi mọi thông báo. Một số công cụ cung cấp các tùy chọn để xử lý phần cuối dòng trong quá trình so sánh; những người khác băm tệp như hiện trạng. Việc biết liệu công cụ của bạn băm tệp dưới dạng nhị phân hay thực hiện chuẩn hóa văn bản trước tiên là điều cần thiết để có thể tái tạo.
Bài học rút ra: byte băm, không phải văn bản — máy tính băm ToolAcre SHA băm các byte bạn dán, vì vậy hãy kiểm tra xem bạn đã dán gì trước
So sánh và xác minh chỉ hoạt động khi bạn băm cùng một byte. Bắt đầu bằng cách xác nhận rằng bạn đang băm chính xác cùng một dữ liệu đầu vào: chạy echo -n (hoặc printf) thay vì echo để tránh dòng mới, chỉ định mã hóa UTF-8 một cách rõ ràng nếu công cụ của bạn cho phép, hãy kiểm tra xem CRLF chưa được trình chỉnh sửa hoặc tiện ích hệ thống chèn vào hay không. Sau đó băm bằng máy tính ToolAcre và công cụ dòng lệnh cạnh nhau. Nếu thông báo trùng khớp thì các byte giống hệt nhau. Nếu không, hãy sử dụng hiển thị số byte và phương pháp kết xuất hex để tìm ra sự khác biệt ẩn.
Khi bạn hiểu vị trí các byte được phân tách, bạn có thể chọn có bình thường hóa chúng để so sánh hay không. Một số tổng kiểm tra nhằm xác minh tính toàn vẹn của tệp chính xác như nó tồn tại trên đĩa, trong trường hợp đó mục tiêu là băm từng byte. Những mục đích khác nhằm xác minh rằng nội dung hiển thị giống nhau, trong trường hợp đó việc chuẩn hóa kết thúc dòng và mã hóa là chính xác. Điều đó cũng không sai; họ trả lời những câu hỏi khác nhau Thuật toán SHA-256 luôn đúng; câu hỏi chỉ là liệu bạn có yêu cầu nó băm cùng một đầu vào trong cả hai trường hợp hay không.