Băm và băm

Tài liệu này áp dụng cho phương pháp sau: Cập nhật API (phiên bản 4): fullHashes.find.

Tổng quan

Danh sách của tính năng Duyệt web an toàn bao gồm các hàm băm SHA256 có độ dài thay đổi (xem phần Nội dung danh sách). Để kiểm tra một URL dựa trên danh sách Duyệt web an toàn (trên máy chủ hoặc trên máy chủ), trước tiên, khách hàng phải tính toán tiền tố băm của URL đó.

Để tính toán tiền tố hàm băm của một URL, hãy làm theo các bước sau:

  1. Chuẩn hoá URL (xem phần Chuẩn hoá).
  2. Tạo biểu thức hậu tố/tiền tố cho URL (xem phần Biểu thức hậu tố/tiền tố).
  3. Tính toán hàm băm có độ dài đầy đủ cho mỗi biểu thức hậu tố/tiền tố (xem phần Tính toán hàm băm).
  4. Tính toán tiền tố hàm băm cho mỗi hàm băm có độ dài đầy đủ (xem phần Tính toán tiền tố băm).

Lưu ý rằng các bước này phản ánh quy trình mà máy chủ Duyệt web an toàn sử dụng để duy trì Duyệt qua danh sách.

Chuẩn hoá

Để bắt đầu, chúng tôi giả định rằng máy khách đã phân tích cú pháp URL và làm cho URL đó hợp lệ theo RFC 2396. Nếu URL sử dụng tên miền quốc tế hoá (IDN), khách hàng phải chuyển đổi URL thành Biểu diễn mã Puny ASCII. URL phải bao gồm một thành phần đường dẫn; tức là mã đó phải có dấu gạch chéo theo sau ("http://google.com/").

Trước tiên, hãy xoá các ký tự tab (0x09), CR (0x0d) và LF (0x0a) khỏi URL. Không xoá các ký tự thoát cho những ký tự này (ví dụ: '%0a').

Tiếp theo, nếu URL kết thúc trong một phân đoạn, hãy xoá phân đoạn đó. Ví dụ: hãy rút ngắn "http://google.com/#frag" vào "http://google.com/".

Thứ ba, liên tục %-unescape URL cho đến khi không còn phần trăm thoát.

Cách chuẩn hoá tên máy chủ:

Trích xuất tên máy chủ từ URL và sau đó:

  1. Xoá tất cả dấu chấm ở đầu và cuối.
  2. Thay thế các dấu chấm liên tiếp bằng một dấu chấm duy nhất.
  3. Nếu tên máy chủ có thể được phân tích cú pháp dưới dạng địa chỉ IP, hãy chuẩn hoá tên máy chủ thành 4 giá trị thập phân được phân tách bằng dấu chấm. Khách hàng phải xử lý mọi phương thức mã hoá địa chỉ IP hợp pháp, bao gồm hệ bát phân, hệ thập lục phân và có ít hơn 4 thành phần.
  4. Viết thường toàn bộ chuỗi.

Cách chuẩn hoá đường dẫn:

  1. Phân giải các chuỗi "/../" và "/./" trong lộ trình theo đang thay thế "/./" bằng "/" và xoá "/../" cùng với đường dẫn trước đó thành phần.
  2. Thay thế các dấu gạch chéo liên tiếp bằng một ký tự dấu gạch chéo duy nhất.

Không áp dụng các quá trình chuẩn hoá đường dẫn này cho các tham số truy vấn.

Trong URL, hãy thoát bằng ký tự phần trăm tất cả ký tự <= ASCII 32, >= 127, "#" hoặc "%". Các ký tự thoát phải sử dụng ký tự hex viết hoa.

Dưới đây là các bài kiểm thử giúp xác thực việc triển khai quy trình chuẩn hoá.

Canonicalize("http://host/%25%32%35") = "http://host/%25";
Canonicalize("http://host/%25%32%35%25%32%35") = "http://host/%25%25";
Canonicalize("http://host/%2525252525252525") = "http://host/%25";
Canonicalize("http://host/asdf%25%32%35asd") = "http://host/asdf%25asd";
Canonicalize("http://host/%%%25%32%35asd%%") = "http://host/%25%25%25asd%25%25";
Canonicalize("http://www.google.com/") = "http://www.google.com/";
Canonicalize("http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77%77%77%2E%65%62%61%79%2E%63%6F%6D/") = "http://168.188.99.26/.secure/www.ebay.com/";
Canonicalize("http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/") = "http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/";
Canonicalize("http://host%23.com/%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A22%252833%252944_55%252B") = "http://host%23.com/~a!b@c%23d$e%25f^00&11*22(33)44_55+";
Canonicalize("http://3279880203/blah") = "http://195.127.0.11/blah";
Canonicalize("http://www.google.com/blah/..") = "http://www.google.com/";
Canonicalize("www.google.com/") = "http://www.google.com/";
Canonicalize("www.google.com") = "http://www.google.com/";
Canonicalize("http://www.evil.com/blah#frag") = "http://www.evil.com/blah";
Canonicalize("http://www.GOOgle.com/") = "http://www.google.com/";
Canonicalize("http://www.google.com.../") = "http://www.google.com/";
Canonicalize("http://www.google.com/foo\tbar\rbaz\n2") ="http://www.google.com/foobarbaz2";
Canonicalize("http://www.google.com/q?") = "http://www.google.com/q?";
Canonicalize("http://www.google.com/q?r?") = "http://www.google.com/q?r?";
Canonicalize("http://www.google.com/q?r?s") = "http://www.google.com/q?r?s";
Canonicalize("http://evil.com/foo#bar#baz") = "http://evil.com/foo";
Canonicalize("http://evil.com/foo;") = "http://evil.com/foo;";
Canonicalize("http://evil.com/foo?bar;") = "http://evil.com/foo?bar;";
Canonicalize("http://\x01\x80.com/") = "http://%01%80.com/";
Canonicalize("http://notrailingslash.com") = "http://notrailingslash.com/";
Canonicalize("http://www.gotaport.com:1234/") = "http://www.gotaport.com/";
Canonicalize("  http://www.google.com/  ") = "http://www.google.com/";
Canonicalize("http:// leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("http://%20leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("%20leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("https://www.securesite.com/") = "https://www.securesite.com/";
Canonicalize("http://host.com/ab%23cd") = "http://host.com/ab%23cd";
Canonicalize("http://host.com//twoslashes?more//slashes") = "http://host.com/twoslashes?more//slashes";

Biểu thức hậu tố/tiền tố

Sau khi URL chính tắc, bước tiếp theo là tạo biểu thức hậu tố/tiền tố. Một biểu thức hậu tố/tiền tố bao gồm hậu tố máy chủ (hoặc máy chủ lưu trữ đầy đủ) và tiền tố đường dẫn (hoặc đường dẫn đầy đủ) như được trình bày trong các ví dụ sau.

Biểu thức hậu tố/tiền tốBiểu thức chính quy tương đương
a.b/mypath/
http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a
http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

Ứng dụng này sẽ tạo thành tối đa 30 tổ hợp tiền tố đường dẫn và hậu tố máy chủ có thể có. Các tổ hợp này chỉ sử dụng thành phần máy chủ lưu trữ và đường dẫn của URL. Lược đồ, tên người dùng, mật khẩu và cổng sẽ bị loại bỏ. Nếu URL bao gồm các tham số truy vấn, thì ít nhất một tham số truy vấn sẽ bao gồm đường dẫn và tham số truy vấn đầy đủ.

Đối với máy chủ lưu trữ, ứng dụng sẽ thử tối đa 5 chuỗi khác nhau. Các loại chiến dịch phụ đó là:

  • Tên máy chủ chính xác trong URL.
  • Tối đa 4 tên máy chủ được tạo bằng cách bắt đầu với 5 thành phần cuối cùng và xoá thành phần ở đầu. Bạn có thể bỏ qua miền cấp cao nhất. Bạn không nên đánh dấu các tên máy chủ bổ sung này nếu máy chủ là địa chỉ IP.

Đối với đường dẫn, ứng dụng sẽ thử tối đa 6 chuỗi khác nhau. Chúng là:

  • Đường dẫn chính xác của URL, bao gồm cả các tham số truy vấn.
  • Đường dẫn chính xác của URL, không có tham số truy vấn.
  • Bốn đường dẫn được hình thành bằng cách bắt đầu ở gốc (/) và nối tiếp nhau đường dẫn bao gồm cả dấu gạch chéo ở cuối.

Các ví dụ sau đây minh hoạ hành vi kiểm tra:

Đối với URL http://a.b.c/1/2.html?param=1, ứng dụng sẽ thử những cách sau các chuỗi có thể có:

a.b.c/1/2.html?param=1
a.b.c/1/2.html
a.b.c/
a.b.c/1/
b.c/1/2.html?param=1
b.c/1/2.html
b.c/
b.c/1/

Đối với URL http://a.b.c.d.e.f.g/1.html, ứng dụng sẽ thử những cách này strings:

a.b.c.d.e.f.g/1.html
a.b.c.d.e.f.g/
(Note: skip b.c.d.e.f.g, since we'll take only the last five hostname components, and the full hostname)
c.d.e.f.g/1.html
c.d.e.f.g/
d.e.f.g/1.html
d.e.f.g/
e.f.g/1.html
e.f.g/
f.g/1.html
f.g/

Đối với URL http://1.2.3.4/1/, ứng dụng sẽ thử những cách này strings:

1.2.3.4/1/
1.2.3.4/

Tính toán hàm băm

Sau khi tạo tập hợp các biểu thức hậu tố/tiền tố, bước tiếp theo là tính toán hàm băm SHA256 có độ dài đầy đủ cho mỗi biểu thức. Dưới đây là một bài kiểm thử đơn vị (ở dạng C giả lập) mà bạn có thể sử dụng để xác thực các phép tính băm.

Ví dụ từ FIPS-180-2:

Unit Test (in pseudo-C)

// Example B1 from FIPS-180-2
string input1 = "abc";
string output1 = TruncatedSha256Prefix(input1, 32);
int expected1[] = { 0xba, 0x78, 0x16, 0xbf };
assert(output1.size() == 4);  // 4 bytes == 32 bits
for (int i = 0; i < output1.size(); i++) assert(output1[i] == expected1[i]);

// Example B2 from FIPS-180-2
string input2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
string output2 = TruncatedSha256Prefix(input2, 48);
int expected2[] = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06 };
assert(output2.size() == 6);
for (int i = 0; i < output2.size(); i++) assert(output2[i] == expected2[i]);

// Example B3 from FIPS-180-2
string input3(1000000, 'a');  // 'a' repeated a million times
string output3 = TruncatedSha256Prefix(input3, 96);
int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
                    0x81, 0xa1, 0xc7, 0xe2 };
assert(output3.size() == 12);
for (int i = 0; i < output3.size(); i++) assert(output3[i] == expected3[i]);

Tính toán tiền tố hàm băm

Cuối cùng, ứng dụng cần tính toán tiền tố hàm băm cho mỗi hàm băm SHA256 có độ dài đầy đủ. Đối với tính năng duyệt web an toàn, tiền tố hàm băm bao gồm 4 đến 32 byte quan trọng nhất của hàm băm SHA256.

Ví dụ từ FIPS-180-2:

  • Ví dụ B1 trong FIPS-180-2
    • Dữ liệu đầu vào là "abc".
    • Thông báo SHA256 là ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • Tiền tố hàm băm 32 bit là ba7816bf.
  • Ví dụ B2 trong FIPS-180-2
    • Dữ liệu đầu vào là "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".
    • Thông báo SHA256 là 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • Tiền tố hàm băm 48 bit là 248d6a61 d206.