Local Database

Google Safe Browsing v5 از مشتری انتظار دارد که یک پایگاه داده محلی را حفظ کند، به جز زمانی که مشتری حالت بی‌درنگ بدون ذخیره‌سازی را انتخاب کند. فرمت و ذخیره سازی این پایگاه داده محلی به مشتری بستگی دارد. محتویات این پایگاه داده محلی را می توان از نظر مفهومی به عنوان یک پوشه حاوی لیست های مختلف به عنوان فایل در نظر گرفت و محتویات این فایل ها هش SHA256 یا پیشوندهای متناظر آنها با پیشوند هش چهار بایتی است که متداول ترین طول هش استفاده می شود.

لیست های موجود

فهرست‌ها با نام‌های متمایزشان که از یک قرارداد نام‌گذاری پیروی می‌کنند، شناسایی می‌شوند که در آن نام پسوندی وجود دارد که نشان‌دهنده طول هش است که باید در لیست انتظار داشته باشید. لیست‌های هش با یک نوع تهدید اما طول هش متفاوت، فهرستی با نام جداگانه خواهند بود که دارای پسوندی است که طول هش را نشان می‌دهد.

لیست های زیر برای استفاده با روش های لیست هش در دسترس هستند.

نام لیست مربوطه v4 ThreatType Enum توضیحات
gc-32b هیچ کدام این لیست یک لیست کش جهانی است. این یک لیست ویژه است که فقط در حالت Real Time استفاده می شود.
se-4b SOCIAL_ENGINEERING این لیست حاوی تهدیدهایی از نوع تهدید SOCIAL_ENGINEERING است.
mw-4b MALWARE این لیست حاوی تهدیداتی از نوع تهدید بدافزار برای پلتفرم های دسکتاپ است.
uws-4b UNWANTED_SOFTWARE این لیست حاوی تهدیداتی از نوع تهدید UNWANTED_SOFTWARE برای پلتفرم های دسکتاپ است.
uwsa-4b UNWANTED_SOFTWARE این لیست حاوی تهدیداتی از نوع تهدید UNWANTED_SOFTWARE برای پلتفرم های اندروید است.
pha-4b POTENTIALLY_HARMFUL_APPLICATION این لیست حاوی تهدیداتی از نوع تهدید POTENTIALLY_HARMFUL_APPLICATION برای پلتفرم های Android است.

لیست‌های اضافی می‌توانند بعداً در دسترس قرار گیرند، در این زمان جدول بالا گسترش می‌یابد، و نتایج حاصل از روش hashList.list نتیجه مشابهی را با لیست‌های به‌روز نشان می‌دهد.

به روز رسانی پایگاه داده

کلاینت مرتباً متد hashList.get یا متد hashLists.batchGet را برای به روز رسانی پایگاه داده فراخوانی می کند. از آنجایی که مشتری معمولی می خواهد چندین لیست را در یک زمان به روز کند، توصیه می شود از روش hashLists.batchGet استفاده کنید.

نام لیست هرگز تغییر نام نخواهد داد. علاوه بر این، هنگامی که یک لیست ظاهر شد، هرگز حذف نخواهد شد (اگر لیست دیگر مفید نباشد، خالی می شود اما به وجود خود ادامه می دهد). بنابراین، مناسب است که این نام ها را در کد سرویس گیرنده Google Safe Browsing کدگذاری کنید.

هم روش hashList.get و هم روش hashLists.batchGet از به روز رسانی های افزایشی پشتیبانی می کنند. استفاده از به روز رسانی های افزایشی باعث صرفه جویی در پهنای باند و بهبود عملکرد می شود. به روز رسانی های افزایشی با ارائه یک دلتا بین نسخه مشتری از لیست و آخرین نسخه لیست کار می کنند. (اگر یک کلاینت به تازگی مستقر شده باشد و هیچ نسخه ای در دسترس نداشته باشد، یک به روز رسانی کامل در دسترس است.) به روز رسانی افزایشی شامل شاخص های حذف و اضافه شده است. ابتدا از مشتری انتظار می رود که ورودی های شاخص های مشخص شده را از پایگاه داده محلی خود حذف کند و سپس اضافات را اعمال کند.

در نهایت، برای جلوگیری از فساد، کلاینت باید داده های ذخیره شده را در مقابل چک جمع ارائه شده توسط سرور بررسی کند. هر زمان که جمع چک مطابقت نداشته باشد، مشتری باید به روز رسانی کامل را انجام دهد.

رمزگشایی محتوای فهرست

رمزگشایی هش ها و پیشوندهای هش

همه لیست ها با استفاده از یک رمزگذاری ویژه برای کاهش اندازه تحویل داده می شوند. این رمزگذاری با تشخیص اینکه لیست‌های مرور ایمن Google از نظر مفهومی حاوی مجموعه‌ای از پیشوندهای هش یا هش هستند، کار می‌کند که از نظر آماری از اعداد صحیح تصادفی قابل تشخیص نیستند. اگر بخواهیم این اعداد صحیح را مرتب کنیم و تفاوت مجاور آنها را بگیریم، انتظار می رود چنین تفاوت مجاور به یک معنا "کوچک" باشد. رمزگذاری Golomb-Rice سپس از این کوچکی سوء استفاده می کند.

فرض کنید که سه عبارت پسوند مسیر میزبان، یعنی a.example.com/ ، b.example.com/ ، و y.example.com/ ، قرار است با استفاده از پیشوندهای هش 4 بایتی منتقل شوند. بعلاوه فرض کنید که پارامتر Rice که با k نشان داده شده است، انتخاب شده است

  1. سرور با محاسبه هش کامل برای این رشته ها شروع می کند که به ترتیب عبارتند از:
291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc  a.example.com/
1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c  b.example.com/
f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03  y.example.com/

سپس سرور پیشوندهای هش 4 بایتی را برای هر یک از موارد فوق تشکیل می دهد که 4 بایت اول هش کامل 32 بایتی است که به عنوان اعداد صحیح 32 بیتی بزرگ endian تفسیر می شود. endianness بزرگ به این واقعیت اشاره دارد که اولین بایت از هش کامل به مهم ترین بایت عدد صحیح 32 بیتی تبدیل می شود. این مرحله به اعداد صحیح 0x291bc542، 0x1d32c508 و 0xf7a502e5 منجر می شود.

لازم است سرور این سه پیشوند هش را به صورت واژگانی (معادل مرتب سازی عددی در big endian) مرتب کند و نتیجه مرتب سازی 0x1d32c508، 0x291bc542، 0xf7a502e5 است. اولین پیشوند هش بدون تغییر در فیلد first_value ذخیره می شود.

سپس سرور دو تفاوت مجاور را محاسبه می کند که به ترتیب 0xbe9003a و 0xce893da3 هستند. با توجه به اینکه k به عنوان 30 انتخاب شده است، سرور این دو عدد را به قسمت های ضریب و قسمت های باقیمانده که به ترتیب 2 و 30 بیت هستند تقسیم می کند. برای عدد اول، قسمت ضریب صفر و باقیمانده 0xbe9003a است. برای عدد دوم، قسمت ضریب 3 است زیرا مهم ترین دو بیت 11 در باینری و بقیه 0xe893da3 است. برای یک ضریب مشخص q به (1 << q) - 1 دقیقاً با استفاده از بیت های 1 + q کدگذاری می شود. باقیمانده مستقیماً با استفاده از k بیت کدگذاری می شود. قسمت ضریب عدد اول به صورت 0 کدگذاری می شود و قسمت باقیمانده به صورت باینری 001011111010010000000000111010 است. قسمت ضریب عدد دوم به صورت 0111 کدگذاری می شود و قسمت باقیمانده 001110100010010011110110100011 است.

هنگامی که این اعداد به یک رشته بایت تبدیل می شوند، اندیان کمی استفاده می شود. از نظر مفهومی ممکن است تصور اینکه یک رشته بیت طولانی از بیت‌های کم‌اهمیت شروع می‌شود، آسان‌تر باشد: بخش ضریب عدد اول را می‌گیریم و قسمت باقیمانده عدد اول را پیش‌فرض می‌کنیم. سپس قسمت ضریب عدد دوم را پیش‌فرض می‌کنیم و قسمت باقیمانده را پیش‌فرض می‌کنیم. این باید به تعداد زیاد زیر منجر شود (خطوط و نظرات اضافه شده برای وضوح):

001110100010010011110110100011 # Second number, remainder part
0111 # Second number, quotient part
001011111010010000000000111010 # First number, remainder part
0 # First number, quotient part

نوشته شده در یک خط این خواهد بود

00111010001001001111011010001101110010111110100100000000001110100

بدیهی است که این تعداد بسیار بیشتر از 8 بیت موجود در یک بایت است. سپس رمزگذاری اندیان کوچک، 8 بیت کم‌اهمیت را در آن عدد می‌گیرد و آن را به عنوان اولین بایت که 01110100 است، خروجی می‌دهد.

0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100

سپس رمزگذاری اندیان کوچک هر بایت را از سمت راست می گیرد و آن را در یک بایت تست قرار می دهد:

01110100
00000000
11010010
10010111
00011011
11101101
01001001
01110100
00000000

مشاهده می شود که از آنجایی که از نظر مفهومی قطعات جدید را به عدد بزرگ سمت چپ اضافه می کنیم (یعنی اضافه کردن بیت های مهم تر) اما از سمت راست (یعنی کم اهمیت ترین بیت ها) رمزگذاری می کنیم، رمزگذاری و رمزگشایی می تواند به صورت تدریجی انجام شود.

این در نهایت نتیجه می دهد

additions_four_bytes {
  first_value: 489866504
  rice_parameter: 30
  entries_count: 2
  encoded_data: "t\000\322\227\033\355It\000"
}

کلاینت به سادگی مراحل بالا را به صورت معکوس دنبال می کند تا پیشوندهای هش را رمزگشایی کند.

رمزگشایی شاخص های حذف

شاخص‌های حذف دقیقاً با همان تکنیک بالا با استفاده از اعداد صحیح 32 بیتی کدگذاری می‌شوند.

فرکانس به روز رسانی

کلاینت باید مقدار برگشتی سرور را در فیلد minimum_wait_duration بررسی کند و از آن برای برنامه ریزی به روز رسانی بعدی پایگاه داده استفاده کند. این مقدار احتمالاً صفر است (فیلد minimum_wait_duration به طور کامل وجود ندارد)، در این صورت مشتری باید فوراً به‌روزرسانی دیگری را انجام دهد.