Băm và băm

Tài liệu này áp dụng cho phương thức sau: Cập nhật API (v4): fullHashes.find.

Tổng quan

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

Để tính toán tiền tố 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 bài viết Biểu thức hậu tố/tiền tố).
  3. Tính toán hàm băm đủ độ dài cho mỗi biểu thức hậu tố/tiền tố (xem bài viết 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 đủ độ dài (xem bài viết Tính toán tiền tố hàm băm).

Xin 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ì danh sách Duyệt web an toàn.

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), thì khách hàng cần chuyển đổi URL thành giá trị biểu thị mã ASCII Puny. URL phải bao gồm một thành phần đường dẫn; nghĩa là URL này phải có một dấu gạch chéo ("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á chuỗi ký tự thoát cho những ký tự này (ví dụ: '%0a').

Thứ hai, nếu URL kết thúc trong một mảnh, hãy xoá mảnh đó. Ví dụ: rút ngắn "http://google.com/#frag" thành "http://google.com/".

Thứ ba, liên tục bỏ thoát phần trăm URL cho đến khi URL này không còn phần trăm thoát nữa.

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

Trích xuất tên máy chủ từ URL rồi:

  1. Xoá tất cả cá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.
  3. Nếu có thể phân tích cú pháp tên máy chủ 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. Máy khách phải xử lý mọi phương thức mã hoá địa chỉ IP hợp pháp, bao gồm cả hệ bát phân, hệ thập lục phân và ít hơn 4 thành phần.
  4. Viết thường của toàn bộ chuỗi.

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

  1. Giải quyết các trình tự "/../" và "/./" trong đường dẫn bằng cách thay thế "/./" bằng "/" và xoá "/../" cùng với thành phần đường dẫn trước đó.
  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 đơn.

Đừng áp dụng các quy tắc chuẩn hoá đường dẫn này cho các tham số truy vấn.

Trong URL, ký tự thoát phần trăm cho tất cả cá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 thử nghiệm để giúp xác thực việc triển khai quá 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 được chuẩn hoá, bước tiếp theo là tạo biểu thức hậu tố/tiền tố. Mỗi biểu thức hậu tố/tiền tố bao gồm một hậu tố máy chủ (hoặc máy chủ lưu trữ đầy đủ) và một tiền tố đường dẫn (hoặc đường dẫn đầy đủ) như trong các ví dụ sau.

Hậu tố/Biểu thức 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 sẽ tạo 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 kết hợp này chỉ sử dụng các thành phần máy chủ và đường dẫn của URL. Giao thứ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 tổ hợp sẽ bao gồm đường dẫn đầy đủ và tham số truy vấn.

Đối với máy chủ, ứng dụng sẽ thử tối đa 5 chuỗi khác nhau. Các yếu tố này 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á liên tiếp thành phần đứng đầu. Bạn có thể bỏ qua miền cấp cao nhất. Bạn không nên kiểm tra các tên máy chủ bổ sung này nếu máy chủ lưu trữ là một địa chỉ IP.

Đối với đường dẫn, ứng dụng sẽ thử tối đa 6 chuỗi khác nhau. Đó 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 từ gốc (/) và nối tiếp các thành phần đường dẫn, bao gồm cả một dấu gạch chéo ở cuối.

Các ví dụ sau 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ử các chuỗi có thể dùng sau:

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ử các chuỗi có thể có sau đây:

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ử các chuỗi có thể có sau đây:

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 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ị (giả lập C) mà bạn có thể sử dụng để xác thực các phép tính hàm 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 từng hàm băm SHA256 có độ dài đầy đủ. Đối với tính năng Duyệt web an toàn, một tiền tố hàm băm bao gồm 4-32 byte quan trọng nhất của hàm băm SHA256.

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

  • Ví dụ B1 từ FIPS-180-2
    • Giá trị nhập là "abc".
    • Chuỗi đại diện SHA256 là ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • Tiền tố hàm băm 32 bit là ba7816bf.
  • Ví dụ B2 từ FIPS-180-2
    • Dữ liệu đầu vào là "abcdbcdecdefdefgefghfghijhijkijkljklmklmnlmnomnopnopq".
    • Chuỗi đại diện SHA256 là 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • Tiền tố băm 48 bit là 248d6a61 d206.