Local Database
Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
La versione 5 di Navigazione sicura di Google si aspetta che il client gestisca un database locale, tranne quando il client sceglie la modalità in tempo reale senza archiviazione. Spetta al cliente il formato e l'archiviazione di questo database locale. I contenuti di questo database locale possono essere concettualmente considerati come una cartella contenente vari elenchi sotto forma di file e i contenuti di questi file sono hash SHA256 o i relativi prefissi corrispondenti, con un prefisso hash di quattro byte che è la lunghezza dell'hash più comunemente utilizzata.
Elenchi disponibili
Gli elenchi sono identificati dai loro nomi distinti che seguono una convenzione di denominazione in cui il nome contiene un suffisso che indica la lunghezza dell'hash che dovresti aspettarti nell'elenco. Gli elenchi di hash con lo stesso tipo di minaccia, ma con una lunghezza dell'hash diversa, saranno un elenco con nome distinto, qualificato con un suffisso che indica la lunghezza dell'hash.
I seguenti elenchi sono disponibili per l'utilizzo con i metodi degli elenchi di hash.
Nome elenco |
Enum ThreatType v4 corrispondente |
Descrizione |
gc-32b |
Nessuno |
Questo è un elenco della cache globale. Si tratta di un elenco speciale utilizzato solo nella modalità di funzionamento in tempo reale. |
se-4b |
SOCIAL_ENGINEERING |
Questo elenco contiene minacce di tipo SOCIAL_ENGINEERING. |
mw-4b |
MALWARE |
Questo elenco contiene minacce del tipo MALWARE per le piattaforme desktop. |
uws-4b |
UNWANTED_SOFTWARE |
Questo elenco contiene minacce del tipo UNWANTED_SOFTWARE per le piattaforme desktop. |
uwsa-4b |
UNWANTED_SOFTWARE |
Questo elenco contiene minacce del tipo UNWANTED_SOFTWARE per le piattaforme Android. |
pha-4b |
POTENTIALLY_HARMFUL_APPLICATION |
Questo elenco contiene minacce del tipo POTENTIALLY_HARMFUL_APPLICATION per le piattaforme Android. |
Altri elenchi possono diventare disponibili in un secondo momento, a quel punto la tabella sopra riportata verrà espansa e i risultati del metodo hashList.list mostreranno un risultato simile con gli elenchi più aggiornati.
Aggiornamenti del database
Il client chiamerà regolarmente il metodo hashList.get o il metodo hashLists.batchGet per aggiornare il database. Poiché il cliente tipico vorrà aggiornare più elenchi contemporaneamente, è consigliabile utilizzare il metodo hashLists.batchGet.
I nomi degli elenchi non verranno mai rinominati. Inoltre, una volta visualizzato, un elenco non verrà mai rimosso (se non è più utile, diventerà vuoto, ma continuerà a esistere). Pertanto, è opportuno codificare questi nomi nel codice client di Google Navigazione sicura.
Sia il metodo hashList.get sia il metodo hashLists.batchGet supportano gli aggiornamenti incrementali. L'utilizzo di aggiornamenti incrementali consente di risparmiare larghezza di banda e migliorare le prestazioni. Gli aggiornamenti incrementali funzionano generando un delta tra la versione dell'elenco del client e la versione più recente dell'elenco. Se un client è stato appena disegnato e non ha versioni disponibili, è disponibile un aggiornamento completo. L'aggiornamento incrementale contiene indici di rimozione e aggiunte. Innanzitutto, il cliente deve rimuovere le voci agli indici specificati dal proprio database locale e poi applicare le aggiunte.
Infine, per evitare la corruzione, il client deve verificare i dati archiviati rispetto al checksum fornito dal server. Ogni volta che il checksum non corrisponde, il client deve eseguire un aggiornamento completo.
Decodifica dei contenuti dell'elenco
Decodifica di hash e prefissi di hash
Tutti gli elenchi vengono pubblicati utilizzando una codifica speciale per ridurre le dimensioni. Questa codifica funziona riconoscendo che gli elenchi di Navigazione sicura di Google contengono, concettualmente, un insieme di hash o prefissi di hash, che sono statisticamente indistinguibili da numeri interi casuali. Se dovessimo ordinare questi numeri interi e prendere la loro differenza adiacente, questa differenza adiacente dovrebbe essere "piccola" in un certo senso. La codifica Golomb-Rice sfrutta questa ridotta dimensione.
Supponiamo che tre espressioni di prefisso del percorso con suffisso host, ovvero a.example.com/
, b.example.com/
e y.example.com/
, debbano essere trasmesse utilizzando preffissi hash di 4 byte. Supponiamo inoltre che il parametro di Rice, indicato con k, sia scelto in modo che
- Il server inizierà calcolando l'hash completo di queste stringhe, che sono rispettivamente:
291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc a.example.com/
1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c b.example.com/
f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03 y.example.com/
Il server forma quindi prefissi di hash di 4 byte per ciascuno dei valori precedenti, ovvero i primi 4 byte dell'hash completo di 32 byte, interpretati come numeri interi a 32 bit big-endian. L'ordine big endian si riferisce al fatto che il primo byte dell'hash completo diventa il byte più significativo dell'intero a 32 bit. Questo passaggio genera i numeri interi 0x291bc542, 0x1d32c508 e 0xf7a502e5.
È necessario che il server ordini questi tre prefissi di hash in ordine alfabetico (equivalente all'ordinamento numerico in big endian) e il risultato dell'ordinamento è 0x1d32c508, 0x291bc542, 0xf7a502e5. Il primo prefisso dell'hash viene memorizzato invariato nel campo first_value
.
Il server calcola quindi le due differenze adiacenti, che sono rispettivamente 0xbe9003a e 0xce893da3. Dato che k è scelto come 30, il server suddivide questi due numeri nelle parti del quoziente e del resto che hanno rispettivamente 2 e 30 bit di lunghezza. Per il primo numero, la parte del quoziente è zero e il resto è 0xbe9003a; per il secondo numero, la parte del quoziente è 3 perché i due bit più significativi sono 11 in binario e il resto è 0xe893da3. Per un determinato quoziente q
, viene codificato in (1 << q) - 1
utilizzando esattamente 1 + q
bit; il resto viene codificato direttamente utilizzando k bit. La parte del quoziente del primo numero è codificata come 0 e la parte del resto è in binario 001011111010010000000000111010; la parte del quoziente del secondo numero è codificata come 0111 e la parte del resto è 001110100010010011110110100011.
Quando questi numeri vengono formattati in una stringa di byte, viene utilizzato il little endian. Concettualmente, può essere più facile immaginare una lunga stringa di bit formata a partire dai bit meno significativi: prendiamo la parte del quoziente del primo numero e anteponiamo la parte del resto del primo numero; poi anteponiamo ulteriormente la parte del quoziente del secondo numero e la parte del resto. Dovresti ottenere il seguente numero elevato (interruzioni di riga e commenti aggiunti per chiarezza):
001110100010010011110110100011 # Second number, remainder part
0111 # Second number, quotient part
001011111010010000000000111010 # First number, remainder part
0 # First number, quotient part
Se scritto in una sola riga, il codice sarà
00111010001001001111011010001101110010111110100100000000001110100
Ovviamente questo numero supera di gran lunga gli 8 bit disponibili in un singolo byte. La codifica little endian prende quindi gli 8 bit meno significativi del numero e li restituisce come primo byte, ovvero 01110100. Per chiarezza, possiamo raggruppare la stringa di bit sopra in gruppi di otto a partire dai bit meno significativi:
0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100
La codifica little endian prende quindi ogni byte da destra e lo inserisce in una stringa di byte:
01110100
00000000
11010010
10010111
00011011
11101101
01001001
01110100
00000000
Poiché concettualmente anteponiamo nuove parti al numero grande a sinistra (ovvero aggiungiamo bit più significativi), ma codifichiamo da destra (ovvero dai bit meno significativi), la codifica e la decodifica possono essere eseguite in modo incrementale.
Il risultato finale è
additions_four_bytes {
first_value: 489866504
rice_parameter: 30
entries_count: 2
encoded_data: "t\000\322\227\033\355It\000"
}
Il client segue semplicemente i passaggi precedenti in ordine inverso per decodificare i prefissi degli hash.
Indici di rimozione della decodifica
Gli indici di rimozione vengono codificati utilizzando la stessa tecnica di cui sopra, con numeri interi a 32 bit.
Frequenza degli aggiornamenti
Il client deve ispezionare il valore restituito dal server nel campo minimum_wait_duration
e utilizzarlo per pianificare il successivo aggiornamento del database. Questo valore potrebbe essere zero (il campo minimum_wait_duration
è completamente mancante), nel qual caso il client DEVE eseguire immediatamente un altro aggiornamento.
Salvo quando diversamente specificato, i contenuti di questa pagina sono concessi in base alla licenza Creative Commons Attribution 4.0, mentre gli esempi di codice sono concessi in base alla licenza Apache 2.0. Per ulteriori dettagli, consulta le norme del sito di Google Developers. Java è un marchio registrato di Oracle e/o delle sue consociate.
Ultimo aggiornamento 2025-07-25 UTC.
[[["Facile da capire","easyToUnderstand","thumb-up"],["Il problema è stato risolto","solvedMyProblem","thumb-up"],["Altra","otherUp","thumb-up"]],[["Mancano le informazioni di cui ho bisogno","missingTheInformationINeed","thumb-down"],["Troppo complicato/troppi passaggi","tooComplicatedTooManySteps","thumb-down"],["Obsoleti","outOfDate","thumb-down"],["Problema di traduzione","translationIssue","thumb-down"],["Problema relativo a esempi/codice","samplesCodeIssue","thumb-down"],["Altra","otherDown","thumb-down"]],["Ultimo aggiornamento 2025-07-25 UTC."],[],[],null,["# Local Database\n\nGoogle Safe Browsing v5 expects the client to maintain a local database, except when the client chooses the [No-Storage Real-Time Mode](/safe-browsing/reference#no-storage-real-time-mode). It is up to the client the format and storage of this local database. The contents of this local database can conceptually be thought of as a folder containing various lists as files, and the contents of these files are SHA256 hashes, or their corresponding prefixes with four byte hash prefix being the most commonly used hash length.\n\n### Available Lists\n\nLists are identified by their distinct names which follows a naming convention where the name contains a suffix that signifies the length of the hash you should expect in the list. Hash lists with the same threat type but different hash length will be a separately named list that's qualified with a suffix that indicates the hash length.\n\nThe following lists are available for use with the hash list methods.\n\n| List Name | Corresponding v4 `ThreatType` Enum | Description |\n|-----------|------------------------------------|------------------------------------------------------------------------------------------------------|\n| `gc-32b` | None | This list is a Global Cache list. It is a special list only used in the Real-Time mode of operation. |\n| `se-4b` | `SOCIAL_ENGINEERING` | This list contains threats of the SOCIAL_ENGINEERING threat type. |\n| `mw-4b` | `MALWARE` | This list contains threats of the MALWARE threat type for desktop platforms. |\n| `uws-4b` | `UNWANTED_SOFTWARE` | This list contains threats of the UNWANTED_SOFTWARE threat type for desktop platforms. |\n| `uwsa-4b` | `UNWANTED_SOFTWARE` | This list contains threats of the UNWANTED_SOFTWARE threat type for Android platforms. |\n| `pha-4b` | `POTENTIALLY_HARMFUL_APPLICATION` | This list contains threats of the POTENTIALLY_HARMFUL_APPLICATION threat type for Android platforms. |\n\nAdditional lists can become available at a later date, at which time the above table will be expanded, and the results from the [hashList.list method](/safe-browsing/reference/rest/v5/hashList/list) will show a similar result with the most up to date lists.\n\n### Database Updates\n\nThe client will regularly call the [hashList.get method](/safe-browsing/reference/rest/v5/hashList/get) or the [hashLists.batchGet method](/safe-browsing/reference/rest/v5/hashLists/batchGet) to update the database. Since the typical client will want to update multiple lists at a time, it is recommended to use [hashLists.batchGet method](/safe-browsing/reference/rest/v5/hashLists/batchGet).\n\nThe list names will never be renamed. Furthermore, once a list has appeared, it will never be removed (if the list is no longer useful, it will become empty but will continue to exist). Therefore, it is appropriate to hard code these names in the Google Safe Browsing client code.\n\nBoth the [hashList.get method](/safe-browsing/reference/rest/v5/hashList/get) and the [hashLists.batchGet method](/safe-browsing/reference/rest/v5/hashLists/batchGet) support incremental updates. Using incremental updates saves bandwidth and improves performance. Incremental updates work by delivering a delta between client's version of the list and the latest version of the list. (If a client is newly deployed and does not have any versions available, a full update is available.) The incremental update contains removal indices and additions. The client is first expected to remove the entries at the specified indices from its local database, and then apply the additions.\n\nFinally, to prevent corruption, the client should check the stored data against the checksum provided by the server. Whenever the checksum does not match, the client should perform a full update.\n\n### Decoding the List Content\n\n#### Decoding Hashes and Hash Prefixes\n\nAll lists are delivered using a special encoding to reduce size. This encoding works by recognizing that Google Safe Browsing lists contain, conceptually, a set of hashes or hash prefixes, which are statistically indistinguishable from random integers. If we were to sort these integers and take their adjacent difference, such adjacent difference is expected to be \"small\" in a sense. [Golomb-Rice encoding](https://en.wikipedia.org/wiki/Golomb_coding) then exploits this smallness.\n\nSuppose that three host-suffix path-prefix expressions, namely `a.example.com/`, `b.example.com/`, and `y.example.com/`, are to be transmitted using 4-byte hash prefixes. Further suppose that the Rice parameter, denoted by k, is chosen to be\n\n1. The server would start by calculating the full hash for these strings, which are, respectively:\n\n 291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc a.example.com/\n 1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c b.example.com/\n f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03 y.example.com/\n\nThe server then forms 4-byte hash prefixes for each of the above, which is the first 4 bytes of the 32-byte full hash, interpreted as big-endian 32-bit integers. The big endianness refers to the fact that the first byte of the full hash becomes the most significant byte of the 32-bit integer. This step results in the integers 0x291bc542, 0x1d32c508, and 0xf7a502e5.\n\nIt is necessary for the server to sort these three hash prefixes lexicographically (equivalent to numerical sorting in big endian), and the result of the sorting is 0x1d32c508, 0x291bc542, 0xf7a502e5. The first hash prefix is stored unchanged in the `first_value` field.\n\nThe server then calculates the two adjacent differences, which are 0xbe9003a and 0xce893da3 respectively. Given that k is chosen to be 30, the server splits these two numbers into the quotient parts and remainder parts that are 2 and 30 bits long respectively. For the first number, the quotient part is zero and the remainder is 0xbe9003a; for the second number, the quotient part is 3 because the most significant two bits are 11 in binary and the remainder is 0xe893da3. For a given quotient `q` it is encoded into `(1 \u003c\u003c q) - 1` using exactly `1 + q` bits; the remainder is encoded directly using k bits. The quotient part of the first number is encoded as 0, and the remainder part is in binary 001011111010010000000000111010; the quotient part of the second number is encoded as 0111, and the remainder part is 001110100010010011110110100011.\n\nWhen these numbers are formed into a byte string, little endian is used. Conceptually it may be easier to imagine a long bitstring being formed starting from the least significant bits: we take the quotient part of the first number and prepend the remainder part of the first number; we then further prepend the quotient part of the second number and prepend the remainder part. This should result in the following large number (linebreaks and comments added for clarity): \n\n 001110100010010011110110100011 # Second number, remainder part\n 0111 # Second number, quotient part\n 001011111010010000000000111010 # First number, remainder part\n 0 # First number, quotient part\n\nWritten in a single line this would be \n\n 00111010001001001111011010001101110010111110100100000000001110100\n\nObviously this number far exceeds the 8 bits available in a single byte. The little endian encoding then takes the least significant 8 bits in that number, and outputs it as the first byte which is 01110100. For clarity, we can group the above bitstring into groups of eight starting from the least significant bits: \n\n 0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100\n\nThe little endian encoding then takes each byte from the right and puts that into a bytestring: \n\n 01110100\n 00000000\n 11010010\n 10010111\n 00011011\n 11101101\n 01001001\n 01110100\n 00000000\n\nIt can be seen that since we conceptually *prepend* new parts to the large number on the left (i.e. adding more significant bits) but we encode from the right (i.e. the least significant bits), the encoding and decoding can be performed incrementally.\n\nThis finally results in \n\n additions_four_bytes {\n first_value: 489866504\n rice_parameter: 30\n entries_count: 2\n encoded_data: \"t\\000\\322\\227\\033\\355It\\000\"\n }\n\nThe client simply follows the above steps in reverse to decode the hash prefixes.\n\n#### Decoding Removal Indices\n\nRemoval indices are encoded using the exact same technique as above using 32-bit integers.\n\n### Update Frequency\n\nThe client should inspect the server's returned value in the field `minimum_wait_duration` and use that to schedule the next update of the database. This value is possibly zero (the field `minimum_wait_duration` is completely missing), in which case the client SHOULD immediately perform another update."]]