URL และการแฮช

เอกสารนี้ใช้กับเมธอดต่อไปนี้ Update API (v4) fullHashes.find

ภาพรวม

รายการของ Google Safe Browsing ประกอบด้วยแฮช SHA256 ที่มีความยาวแปรผัน (ดูเนื้อหารายการ) หากต้องการตรวจสอบ URL กับรายการของ Google Safe Browsing (ทั้งในเครื่องหรือในเซิร์ฟเวอร์) ไคลเอ็นต์ต้องตรวจสอบก่อน ประมวลผลคำนำหน้าแฮชของ URL นั้น

หากต้องการคำนวณค่าแฮชนำหน้าของ URL ให้ทำตามขั้นตอนต่อไปนี้

  1. ทำให้ URL เป็น Canonical (ดูการแปลงข้อมูล)
  2. สร้างนิพจน์ต่อท้าย/คำนำหน้าสําหรับ URL (ดูนิพจน์ต่อท้าย/คํานําหน้า)
  3. คํานวณแฮชแบบเต็มความยาวสําหรับนิพจน์ส่วนต่อท้าย/ส่วนหน้าแต่ละรายการ (ดูการคํานวณแฮช)
  4. ประมวลผลคำนำหน้าแฮชสำหรับแฮชแบบเต็มแต่ละรายการ (ดูการคํานวณคํานําหน้าแฮช)

โปรดทราบว่าขั้นตอนเหล่านี้จะจำลองกระบวนการที่เซิร์ฟเวอร์ Google Safe Browsing ใช้ในการปกป้อง Google Safe Browsing การเรียกดูลิสต์

การกำหนดหน้า Canonical

ในการเริ่มต้น เราสมมติว่าไคลเอ็นต์ได้แยกวิเคราะห์ URL และทำให้ URL ถูกต้องตาม RFC 2396 หาก URL ใช้ชื่อโดเมนสากล (IDN) ไคลเอ็นต์ควรแปลง URL เป็นการแสดงผล Punycode รูปแบบ ASCII URL ต้องมีคอมโพเนนต์เส้นทาง กล่าวคือต้องมีเครื่องหมายทับต่อท้าย ("http://google.com/")

ก่อนอื่น ให้นำอักขระ Tab (0x09), CR (0x0d) และ LF (0x0a) ออกจาก URL อย่านำลำดับหลีกสำหรับอักขระเหล่านี้ออก (เช่น "%0a")

ในกรณีที่ URL ลงท้ายด้วยส่วนย่อย ให้นำส่วนย่อยออก เช่น ย่อ "http://google.com/#frag" เป็น "http://google.com/"

ข้อที่ 3 ให้ Percent-unEscape กับ URL ซ้ำๆ จนกว่าจะไม่มี Escape เป็นเปอร์เซ็นต์แล้ว

หากต้องการทำให้ชื่อโฮสต์เป็นรูปแบบมาตรฐาน ให้ทำดังนี้

ดึงข้อมูลชื่อโฮสต์จาก URL แล้วทําดังนี้

  1. นําจุดขึ้นต้นและต่อท้ายออกทั้งหมด
  2. แทนที่จุดที่เรียงต่อกันด้วยจุดเดียว
  3. หากสามารถแยกวิเคราะห์ชื่อโฮสต์เป็นที่อยู่ IP ให้ทําให้เป็นมาตรฐาน ค่าทศนิยมที่คั่นด้วยจุด 4 ค่า ไคลเอ็นต์ควรจัดการการเข้ารหัสที่อยู่ IP ตามกฎหมาย รวมเลขฐานแปด เลขฐานสิบหก และองค์ประกอบน้อยกว่า 4 ส่วน
  4. ลดทั้งสตริง

วิธีกำหนดเส้นทาง

  1. แก้ไขลําดับ "/../" และ "/./" ในเส้นทางโดยแทนที่ "/./" ด้วย "/" และนํา "/../" ออกพร้อมกับคอมโพเนนต์เส้นทางก่อนหน้า
  2. แทนที่เครื่องหมายทับติดกันด้วยอักขระเครื่องหมายทับตัวเดียว

อย่าใช้การกำหนดเส้นทาง Canonical เหล่านี้กับพารามิเตอร์การค้นหา

ใน URL ให้ใช้อักขระหลีกเปอร์เซ็นต์กับอักขระทั้งหมดที่ <= ASCII 32, >= 127, "#" หรือ "%" โดยควรใช้อักขระฐาน 16 พิมพ์ใหญ่

ด้านล่างนี้คือการทดสอบที่จะช่วยตรวจสอบการติดตั้งใช้งานการจัดทำดัชนีตามลําดับชั้น

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";

นิพจน์คำต่อท้าย/คำนำหน้า

เมื่อ URL ได้รับการทำให้เป็น Canonical แล้ว ขั้นตอนถัดไปคือการสร้างนิพจน์ส่วนต่อท้าย/ส่วนนำหน้า ชิ้น นิพจน์คำต่อท้าย/คำนำหน้าประกอบด้วยคำต่อท้ายโฮสต์ (หรือโฮสต์แบบเต็ม) และคำนำหน้าเส้นทาง (หรือเส้นทางแบบเต็ม) ดังที่แสดงในตัวอย่างเหล่านี้

นิพจน์คำต่อท้าย/คำนำหน้านิพจน์ทั่วไปที่เทียบเท่า
a.b/mypath/
http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a
http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

ไคลเอ็นต์จะสร้างชุดค่าผสมนามสกุลโฮสต์และคำนำหน้าเส้นทางที่เป็นไปได้สูงสุด 30 ชุด ชุดค่าผสมเหล่านี้ใช้เฉพาะคอมโพเนนต์ของโฮสต์และเส้นทางของ URL ดังกล่าว รูปแบบ ชื่อผู้ใช้ รหัสผ่านและพอร์ตจะถูกยกเลิก หาก URL มีพารามิเตอร์การค้นหา พารามิเตอร์ จะมีทั้งเส้นทางและพารามิเตอร์การค้นหา

สำหรับโฮสต์ ไคลเอ็นต์จะลองสตริงที่แตกต่างกันไม่เกิน 5 รายการ ดังนี้

  • ชื่อโฮสต์ใน URL ตรงกัน
  • ชื่อโฮสต์ได้สูงสุด 4 รายการ โดยเริ่มจากคอมโพเนนต์ 5 รายการสุดท้ายแล้วนําคอมโพเนนต์หน้าออกทีละรายการ คุณข้ามโดเมนระดับบนสุดได้ คุณไม่ควรตรวจสอบชื่อโฮสต์เพิ่มเติมเหล่านี้หากโฮสต์เป็นที่อยู่ IP

สำหรับเส้นทาง ไคลเอ็นต์จะลองสตริงที่แตกต่างกันไม่เกิน 6 สตริง ดังนี้

  • เส้นทางที่แน่นอนของ URL ซึ่งรวมถึงพารามิเตอร์การค้นหา
  • เส้นทางที่แน่นอนของ URL ที่ไม่มีพารามิเตอร์การค้นหา
  • เส้นทาง 4 เส้นทางที่สร้างขึ้นโดยเริ่มจากรูท (/) และต่อท้ายด้วยคอมโพเนนต์เส้นทางตามลำดับ รวมถึงเครื่องหมายทับต่อท้าย

ตัวอย่างต่อไปนี้แสดงลักษณะการทํางานของการตรวจสอบ

สำหรับ URL http://a.b.c/1/2.html?param=1 ไคลเอ็นต์จะลอง สตริงที่เป็นไปได้:

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/

สำหรับ URL http://a.b.c.d.e.f.g/1.html ไคลเอ็นต์จะลองดำเนินการตาม URL เหล่านี้ 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/

สำหรับ URL http://1.2.3.4/1/ ไคลเอ็นต์จะลองดำเนินการตาม URL เหล่านี้ strings:

1.2.3.4/1/
1.2.3.4/

การประมวลผลแฮช

เมื่อสร้างชุดของนิพจน์คำต่อท้าย/คำนำหน้าแล้ว ขั้นตอนถัดไปคือการคำนวณ แฮช SHA256 แบบเต็มสำหรับแต่ละนิพจน์ การทดสอบ 1 หน่วย (ในรูปแบบ Pseudo-C) คุณสามารถใช้เพื่อตรวจสอบ การคำนวณแฮชแสดงอยู่ด้านล่าง

ตัวอย่างจาก 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]);

การคํานวณคำนำหน้าแฮช

สุดท้าย ลูกค้าต้องคํานวณคำนำหน้าแฮชสำหรับแฮช SHA256 แบบเต็มแต่ละรายการ เพื่อความปลอดภัย การเรียกดูนั้น แฮชนำหน้าประกอบด้วยแฮช SHA256 จำนวน 4-32 ไบต์ที่มีนัยสำคัญที่สุด

ตัวอย่างจาก FIPS-180-2:

  • ตัวอย่าง B1 จาก FIPS-180-2
    • อินพุตคือ "abc"
    • ไดเจสต์ SHA256 คือ ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
    • คำนำหน้าแฮช 32 บิตคือ ba7816bf
  • ตัวอย่าง ข. จาก FIPS-180-2
    • อินพุตคือ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopnopq"
    • SHA256 digest is 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • คำนำหน้าแฮช 48 บิตคือ 248d6a61 d206