عناوين URL والتجزئة

ينطبق هذا المستند على الطريقة التالية: Update API (الإصدار 4): fullHashes.find.

نظرة عامة

تتألف قوائم التصفح الآمن من تجزئات SHA256 متغيرة الطول (راجع إدراج المحتويات). للتحقّق من عنوان URL ومقارنته بقائمة "التصفّح الآمن" (إما محليًا أو على الخادم)، على العملاء أولاً احتساب بادئة التجزئة لعنوان URL هذا.

لحساب بادئة التجزئة لعنوان URL، اتّبِع الخطوات التالية:

  1. يمكنك تحديد عنوان URL الأساسي (راجِع تحديد عنوان URL الأساسي).
  2. أنشئ تعبيرات اللاحقة/البادئة لعنوان URL (راجِع تعبيرات اللاحقة/البادئة).
  3. احسب التجزئة الكاملة لكل تعبير لاحقة/بادئة (راجِع عمليات حساب التجزئة).
  4. احسب بادئة التجزئة لكل تجزئة كاملة (راجِع عمليات احتساب بادئة التجزئة).

يُرجى العلم أنّ هذه الخطوات تعكس العملية التي يستخدمها خادم "التصفّح الآمن" للاحتفاظ بقوائم "التصفّح الآمن".

تحديد عنوان URL الأساسي

للبدء، نفترض أنّ العميل قد حلّل عنوان URL وجعله صالحًا وفقًا لمعيار RFC 2396. إذا كان عنوان URL يستخدم اسم نطاق دوليًا (IDN)، على العميل تحويل عنوان URL إلى تمثيل ASCII Punycode. يجب أن يشتمل عنوان URL على مكون مسار، أي يجب أن يحتوي على شرطة مائلة لاحقة ("http://google.com/").

أولاً، يجب إزالة أحرف Tab (0x09) وCR (0x0d) وLF (0x0a) من عنوان URL. يُرجى عدم إزالة تسلسلات الإلغاء لهذه الأحرف (مثل "%0a").

ثانيًا، إذا كان عنوان URL ينتهي بجزء، يجب إزالة الكسر. على سبيل المثال، اختصِر "http://google.com/#frag" لتصبح "http://google.com/".

ثالثًا، يتم بشكل متكرّر عدم إلغاء نسبة مئوية من عنوان URL حتى لا يتوفر مزيد من أحرف الإلغاء في النسبة المئوية.

لتحديد عنوان المضيف الأساسي:

استخرِج اسم المضيف من عنوان URL، ثم:

  1. يجب إزالة جميع النقاط البادئة واللاحقة.
  2. استبدِل النقاط المتتالية بنقطة واحدة.
  3. وإذا كان من الممكن تحليل اسم المضيف كعنوان IP، عليك تسويته إلى قيم أعداد عشرية مفصولة بنقاط يبلغ عددها 4 نقاط. يجب أن يتولّى العميل معالجة أي ترميز قانوني لعنوان IP، بما في ذلك الترميز الثماني والست عشري وأقل من أربعة مكونات.
  4. صغِّر السلسلة بأكملها.

لتحديد عنوان URL الأساسي:

  1. حل التسلسلات "/../" و "/./" في المسار عن طريق استبدال "/./" بـ "/" وإزالة "/../" مع مكوِّن المسار السابق.
  2. استبدال الشرطة المائلة المتتالية بحرف شرطة مائلة واحدة.

ولا تطبِّق عمليات تحديد عنوان URL الأساسي للمسار على مَعلمات طلب البحث.

في عنوان URL، يتم تخطي نسبة الإلغاء في جميع الأحرف في شكل <= ASCII 32 أو >= 127 أو "#" أو "%". ويجب أن تستخدم أحرف الإلغاء أحرفًا سداسية عشرية كبيرة.

في ما يلي اختبارات للمساعدة في التحقّق من صحة تنفيذ عملية تحديد عنوان URL الأساسي.

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 الأساسي، تكون الخطوة التالية هي إنشاء تعبيرات اللاحقة/البادئة. يتكون كل تعبير لاحقة/بادئة من لاحقة مضيف (أو مضيف كامل) وبادئة مسار (أو مسار كامل) كما هو موضح في هذه الأمثلة.

تعبير اللاحقة/البادئةالتعبير العادي المكافئ
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 يحتوي على مَعلمات طلب البحث، ستتضمن مجموعة واحدة على الأقل المسار الكامل ومَعلمات طلب البحث.

بالنسبة إلى المضيف، سيحاول العميل تجربة خمس سلاسل مختلفة كحد أقصى. وهي:

  • اسم المضيف الدقيق في عنوان URL.
  • يتم تشكيل ما يصل إلى أربعة أسماء مضيفين من خلال البدء بآخر خمسة مكونات وإزالة العنصر الرئيسي بالتتابع. يمكن تخطّي نطاق المستوى الأعلى. يجب عدم التحقّق من أسماء المضيفين الإضافية هذه إذا كان المضيف هو عنوان IP.

بالنسبة إلى المسار، سيحاول العميل تجربة ست سلاسل مختلفة كحدّ أقصى. وهي:

  • المسار الدقيق لعنوان URL، بما في ذلك مَعلمات طلب البحث.
  • المسار الدقيق لعنوان URL، بدون مَعلمات طلب البحث.
  • المسارات الأربعة التي تكون بالبدء من الجذر (/) وإلحاق مكوّنات المسار بالتتابع، بما في ذلك الشرطة المائلة اللاحقة.

توضّح الأمثلة التالية سلوك عمليات التحقّق:

بالنسبة إلى عنوان 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، سيجرّب العميل هذه السلاسل المحتملة:

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/، سيجرّب العميل هذه السلاسل المحتملة:

1.2.3.4/1/
1.2.3.4/

العمليات الحسابية للتجزئة

بعد إنشاء مجموعة تعبيرات اللاحقة/البادئة، تتمثل الخطوة التالية في احتساب تجزئة SHA256 الكاملة لكل تعبير. ويتوفر أدناه اختبار وحدة (في 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 كاملة الطول. بالنسبة إلى التصفُّح الآمن، تتألف بادئة التجزئة من أهم 4 إلى 32 بايت من تجزئة SHA256.

أمثلة من FIPS-180-2:

  • مثال على B1 من FIPS-180-2
    • الإدخال هو "abc".
    • ملخص SHA256 هو ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • بادئة التجزئة 32 بت هي ba7816bf.
  • مثال على كائن B2 من FIPS-180-2
    • الإدخال هو "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".
    • ملخص SHA256 هو 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • بادئة التجزئة 48 بت هي 248d6a61 d206.