Local Database

Google Safe Browsing v5 mengharapkan klien untuk mengelola database lokal, kecuali jika klien memilih Mode Real-Time Tanpa Penyimpanan. Format dan penyimpanan database lokal ini bergantung pada klien. Secara konseptual, isi database lokal ini dapat dianggap sebagai folder yang berisi berbagai daftar sebagai file, dan isi file ini adalah hash SHA256, atau awalan yang sesuai dengan awalan hash empat byte yang merupakan panjang hash yang paling umum digunakan.

Daftar yang Tersedia

Daftar diidentifikasi dengan nama uniknya yang mengikuti konvensi penamaan dengan nama yang berisi akhiran yang menunjukkan panjang hash yang akan Anda temukan dalam daftar. Daftar hash dengan jenis ancaman yang sama, tetapi panjang hash yang berbeda akan menjadi daftar yang diberi nama secara terpisah dan memenuhi syarat dengan akhiran yang menunjukkan panjang hash.

Daftar berikut tersedia untuk digunakan dengan metode daftar hash.

Nama Daftar Enum ThreatType v4 yang sesuai Deskripsi
gc-32b Tidak ada Daftar ini adalah daftar Cache Global. Ini adalah daftar khusus yang hanya digunakan dalam mode operasi Real-Time.
se-4b SOCIAL_ENGINEERING Daftar ini berisi ancaman dari jenis ancaman SOCIAL_ENGINEERING.
mw-4b MALWARE Daftar ini berisi ancaman dari jenis ancaman MALWARE untuk platform desktop.
uws-4b UNWANTED_SOFTWARE Daftar ini berisi ancaman dari jenis ancaman UNWANTED_SOFTWARE untuk platform desktop.
uwsa-4b UNWANTED_SOFTWARE Daftar ini berisi ancaman dari jenis ancaman UNWANTED_SOFTWARE untuk platform Android.
pha-4b POTENTIALLY_HARMFUL_APPLICATION Daftar ini berisi ancaman jenis ancaman POTENTIALLY_HARMFUL_APPLICATION untuk platform Android.

Daftar tambahan dapat tersedia di lain waktu, saat tabel di atas akan diperluas, dan hasil dari metode hashList.list akan menampilkan hasil yang serupa dengan daftar terbaru.

Update Database

Klien akan memanggil metode hashList.get atau metode hashLists.batchGet secara berkala untuk memperbarui database. Karena klien biasanya ingin memperbarui beberapa daftar sekaligus, sebaiknya gunakan metode hashLists.batchGet.

Nama daftar tidak akan pernah diganti. Selain itu, setelah muncul, daftar tidak akan pernah dihapus (jika daftar tidak lagi berguna, daftar akan menjadi kosong, tetapi akan tetap ada). Oleh karena itu, sebaiknya hard code nama ini di kode klien Google Safe Browsing.

Metode hashList.get dan metode hashLists.batchGet mendukung update inkremental. Menggunakan update inkremental akan menghemat bandwidth dan meningkatkan performa. Update inkremental berfungsi dengan mengirimkan delta antara versi daftar klien dan versi daftar terbaru. (Jika klien baru di-deploy dan tidak memiliki versi yang tersedia, update lengkap akan tersedia.) Update inkremental berisi indeks penghapusan dan penambahan. Klien pertama-tama diharapkan menghapus entri pada indeks yang ditentukan dari database lokalnya, lalu menerapkan penambahan.

Terakhir, untuk mencegah kerusakan, klien harus memeriksa data yang disimpan dengan checksum yang disediakan oleh server. Setiap kali checksum tidak cocok, klien harus melakukan update penuh.

Mendekode Konten Daftar

Mendekode Hash dan Awalan Hash

Semua daftar dikirim menggunakan encoding khusus untuk mengurangi ukuran. Encoding ini berfungsi dengan mengenali bahwa daftar Safe Browsing Google secara konseptual berisi kumpulan hash atau awalan hash, yang secara statistik tidak dapat dibedakan dari bilangan bulat acak. Jika kita mengurutkan bilangan bulat ini dan mengambil perbedaan yang berdekatan, perbedaan yang berdekatan tersebut diharapkan "kecil". Encoding Golomb-Rice kemudian memanfaatkan kecilnya ukuran ini.

Misalkan tiga ekspresi awalan jalur akhiran host, yaitu a.example.com/, b.example.com/, dan y.example.com/, akan dikirim menggunakan awalan hash 4 byte. Selanjutnya, anggap parameter Rice, yang dilambangkan dengan k, dipilih menjadi

  1. Server akan memulai dengan menghitung hash lengkap untuk string ini, yang masing-masing adalah:
291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc  a.example.com/
1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c  b.example.com/
f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03  y.example.com/

Server kemudian membentuk awalan hash 4 byte untuk setiap hal di atas, yang merupakan 4 byte pertama dari hash lengkap 32 byte, yang ditafsirkan sebagai bilangan bulat 32-bit big-endian. Big endian mengacu pada fakta bahwa byte pertama dari hash lengkap menjadi byte yang paling signifikan dari bilangan bulat 32-bit. Langkah ini menghasilkan bilangan bulat 0x291bc542, 0x1d32c508, dan 0xf7a502e5.

Server harus mengurutkan tiga awalan hash ini secara leksikografis (setara dengan pengurutan numerik dalam big endian), dan hasil pengurutannya adalah 0x1d32c508, 0x291bc542, 0xf7a502e5. Awalan hash pertama disimpan tanpa perubahan di kolom first_value.

Server kemudian menghitung dua perbedaan yang berdekatan, yaitu 0xbe9003a dan 0xce893da3. Mengingat bahwa k dipilih menjadi 30, server akan membagi kedua angka ini menjadi bagian hasil bagi dan bagian sisanya yang masing-masing panjangnya 2 dan 30 bit. Untuk angka pertama, bagian hasil bagi adalah nol dan sisanya adalah 0xbe9003a; untuk angka kedua, bagian hasil bagi adalah 3 karena dua bit yang paling signifikan adalah 11 dalam biner dan sisanya adalah 0xe893da3. Untuk kuadrat q tertentu, kuadrat tersebut dienkode menjadi (1 << q) - 1 menggunakan tepat 1 + q bit; sisanya dienkode langsung menggunakan k bit. Bagian hasil bagi dari angka pertama dienkode sebagai 0, dan bagian sisanya dalam biner 001011111010010000000000111010; bagian hasil bagi dari angka kedua dienkode sebagai 0111, dan bagian sisanya adalah 001110100010010011110110100011.

Saat angka ini dibentuk menjadi string byte, little endian akan digunakan. Secara konseptual, mungkin lebih mudah untuk membayangkan bitstring panjang yang terbentuk mulai dari bit yang paling tidak signifikan: kita mengambil bagian hasil bagi dari angka pertama dan menambahkan bagian sisanya dari angka pertama; lalu kita menambahkan bagian hasil bagi dari angka kedua dan menambahkan bagian sisanya. Tindakan ini akan menghasilkan angka besar berikut (pemisah baris dan komentar ditambahkan untuk kejelasan):

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

Jika ditulis dalam satu baris, kode ini akan menjadi

00111010001001001111011010001101110010111110100100000000001110100

Jumlah ini jelas jauh melebihi 8 bit yang tersedia dalam satu byte. Encoding little endian kemudian mengambil 8 bit yang paling tidak signifikan dalam angka tersebut, dan menampilkannya sebagai byte pertama yaitu 01110100. Untuk memperjelas, kita dapat mengelompokkan bitstring di atas menjadi grup delapan, dimulai dari bit yang paling tidak signifikan:

0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100

Encoding little endian kemudian mengambil setiap byte dari sebelah kanan dan memasukkannya ke dalam bytestring:

01110100
00000000
11010010
10010111
00011011
11101101
01001001
01110100
00000000

Dapat dilihat bahwa karena secara konseptual kita menambahkan bagian baru ke angka besar di sebelah kiri (yaitu menambahkan bit yang lebih signifikan), tetapi kita mengenkode dari sebelah kanan (yaitu bit yang paling tidak signifikan), encoding dan decoding dapat dilakukan secara bertahap.

Hal ini akhirnya menghasilkan

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

Klien cukup mengikuti langkah-langkah di atas secara terbalik untuk mendekode awalan hash.

Mendekode Indeks Penghapusan

Indeks penghapusan dienkode menggunakan teknik yang sama persis seperti di atas menggunakan bilangan bulat 32-bit.

Frekuensi Update

Klien harus memeriksa nilai yang ditampilkan server di kolom minimum_wait_duration dan menggunakannya untuk menjadwalkan update database berikutnya. Nilai ini mungkin nol (kolom minimum_wait_duration benar-benar tidak ada), dalam hal ini klien HARUS segera melakukan update lain.