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

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

نظرة عامة

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

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

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

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

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

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

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

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

ثالثًا، يتم تكرار إلغاء النسبة المئوية لعنوان URL بشكل متكرر حتى لا يتم الخروج من النسبة المئوية بعد ذلك.

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

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

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

لتحديد مسار أساسي:

  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 الكاملة لكل تعبير. في ما يلي اختبار وحدة (في صورة زائفة) يمكنك استخدامه للتحقق من صحة حسابات التجزئة لديك.

أمثلة من 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 f20015.
    • بادئة تجزئة 32 بت هي ba7816bf.
  • المثال B2 من FIPS-180-2
    • الإدخال هو "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".
    • الملخص SHA256 هو 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • وتكون بادئة تجزئة 48 بت هي 248d6a61 d206.