La version 5 de la navigation sécurisée Google s'attend à ce que le client gère une base de données locale, sauf lorsqu'il choisit le mode en temps réel sans stockage. C'est au client de définir le format et le stockage de cette base de données locale. Le contenu de cette base de données locale peut être conceptualisé comme un dossier contenant diverses listes sous forme de fichiers. Le contenu de ces fichiers est constitué de hachages SHA256 ou de leurs préfixes correspondants, la longueur de hachage la plus couramment utilisée étant de quatre octets.
Listes disponibles
Les listes sont identifiées par leur nom distinct, qui suit une convention d'attribution de noms dans laquelle le nom contient un suffixe qui indique la longueur du hachage que vous devez attendre dans la liste. Les listes de hachage ayant le même type de menace, mais une longueur de hachage différente, sont des listes distinctes portant un nom et un suffixe qui indiquent la longueur du hachage.
Les listes suivantes sont disponibles pour les méthodes de liste de hachage.
Nom de la liste | Enum ThreatType v4 correspondant |
Description |
---|---|---|
gc-32b |
Aucun | Il s'agit d'une liste de cache global. Il s'agit d'une liste spéciale utilisée uniquement en mode de fonctionnement en temps réel. |
se-4b |
SOCIAL_ENGINEERING |
Cette liste contient des menaces de type SOCIAL_ENGINEERING. |
mw-4b |
MALWARE |
Cette liste contient des menaces de type MALWARE pour les plates-formes de bureau. |
uws-4b |
UNWANTED_SOFTWARE |
Cette liste contient les menaces de type UNWANTED_SOFTWARE pour les plates-formes de bureau. |
uwsa-4b |
UNWANTED_SOFTWARE |
Cette liste contient les menaces de type UNWANTED_SOFTWARE pour les plates-formes Android. |
pha-4b |
POTENTIALLY_HARMFUL_APPLICATION |
Cette liste contient les menaces de type POTENTIALLY_HARMFUL_APPLICATION pour les plates-formes Android. |
D'autres listes peuvent être disponibles à une date ultérieure. Le tableau ci-dessus sera alors développé, et les résultats de la méthode hashList.list afficheront un résultat similaire avec les listes les plus à jour.
Mises à jour de la base de données
Le client appelle régulièrement la méthode hashList.get ou la méthode hashLists.batchGet pour mettre à jour la base de données. Étant donné que le client type souhaite généralement mettre à jour plusieurs listes à la fois, nous vous recommandons d'utiliser la méthode hashLists.batchGet.
Les noms des listes ne seront jamais renommés. De plus, une fois qu'une liste est apparue, elle ne sera jamais supprimée (si elle n'est plus utile, elle deviendra vide, mais continuera d'exister). Il est donc approprié de coder en dur ces noms dans le code client de la navigation sécurisée Google.
La méthode hashList.get et la méthode hashLists.batchGet sont toutes deux compatibles avec les mises à jour incrémentielles. L'utilisation de mises à jour incrémentielles permet d'économiser de la bande passante et d'améliorer les performances. Les mises à jour incrémentielles fonctionnent en fournissant un delta entre la version de la liste du client et la dernière version de la liste. (Si un client vient d'être déployé et qu'aucune version n'est disponible, une mise à jour complète est disponible.) La mise à jour incrémentielle contient des indices de suppression et d'ajout. Le client doit d'abord supprimer les entrées aux indices spécifiés de sa base de données locale, puis appliquer les ajouts.
Enfin, pour éviter toute corruption, le client doit comparer les données stockées à la somme de contrôle fournie par le serveur. Chaque fois que la somme de contrôle ne correspond pas, le client doit effectuer une mise à jour complète.
Décoder le contenu de la liste
Décoder les hachages et les préfixes de hachage
Toutes les listes sont transmises à l'aide d'un encodage spécial pour réduire leur taille. Cet encodage fonctionne en reconnaissant que les listes de Google Safe Browsing contiennent, conceptuellement, un ensemble de hachages ou de préfixes de hachage, qui sont statistiquement indiscernables des entiers aléatoires. Si nous trions ces entiers et prenons leur différence adjacente, cette différence adjacente devrait être "petite" dans un sens. L'encodage Golomb-Rice exploite ensuite cette petite taille.
Supposons que trois expressions de préfixe de chemin de suffixe d'hôte, à savoir a.example.com/
, b.example.com/
et y.example.com/
, doivent être transmises à l'aide de préfixes de hachage de 4 octets. Supposons également que le paramètre Rice, noté k, est choisi comme suit :
- Le serveur commence par calculer le hachage complet de ces chaînes, qui sont respectivement:
291bc5421f1cd54d99afcc55d166e2b9fe42447025895bf09dd41b2110a687dc a.example.com/
1d32c5084a360e58f1b87109637a6810acad97a861a7769e8f1841410d2a960c b.example.com/
f7a502e56e8b01c6dc242b35122683c9d25d07fb1f532d9853eb0ef3ff334f03 y.example.com/
Le serveur forme ensuite des préfixes de hachage de 4 octets pour chacun des éléments ci-dessus, qui correspondent aux quatre premiers octets du hachage complet de 32 octets, interprétés comme des entiers 32 bits big-endian. L'ordre big endian fait référence au fait que le premier octet du hachage complet devient l'octet le plus significatif de l'entier 32 bits. Cette étape génère les entiers 0x291bc542, 0x1d32c508 et 0xf7a502e5.
Le serveur doit trier ces trois préfixes de hachage de manière lexicographique (équivalent au tri numérique en big endian). Le résultat du tri est 0x1d32c508, 0x291bc542 et 0xf7a502e5. Le premier préfixe de hachage est stocké tel quel dans le champ first_value
.
Le serveur calcule ensuite les deux différences adjacentes, qui sont respectivement 0xbe9003a et 0xce893da3. Étant donné que k est défini sur 30, le serveur divise ces deux nombres en parties quotient et reste, respectivement de 2 et 30 bits. Pour le premier nombre, la partie quotient est nulle et le reste est 0xbe9003a. Pour le deuxième nombre, la partie quotient est 3, car les deux bits les plus significatifs sont 11 en binaire, et le reste est 0xe893da3. Pour un quotient q
donné, il est encodé dans (1 << q) - 1
à l'aide d'exactement 1 + q
bits. Le reste est encodé directement à l'aide de k bits. La partie quotient du premier nombre est codée sous la forme 0, et la partie reste est 001011111010010000000000111010 au format binaire. La partie quotient du deuxième nombre est codée sous la forme 0111, et la partie reste est 001110100010010011110110100011.
Lorsque ces nombres sont formés en chaîne d'octets, l'ordre little-endian est utilisé. Conceptuellement, il peut être plus facile d'imaginer qu'une longue chaîne de bits est formée à partir des bits les moins significatifs: nous prenons la partie quotient du premier nombre et ajoutons la partie reste du premier nombre ; nous ajoutons ensuite la partie quotient du deuxième nombre et la partie reste. Vous devriez obtenir le grand nombre suivant (les sauts de ligne et les commentaires ont été ajoutés pour plus de clarté):
001110100010010011110110100011 # Second number, remainder part
0111 # Second number, quotient part
001011111010010000000000111010 # First number, remainder part
0 # First number, quotient part
Écrit sur une seule ligne, cela donne
00111010001001001111011010001101110010111110100100000000001110100
Évidemment, ce nombre dépasse de loin les 8 bits disponibles dans un seul octet. L'encodage little-endian prend ensuite les huit bits les moins significatifs de ce nombre et les affiche sous la forme du premier octet, qui est 01110100. Pour plus de clarté, nous pouvons regrouper la chaîne de bits ci-dessus en groupes de huit à partir des bits les moins significatifs:
0 01110100 01001001 11101101 00011011 10010111 11010010 00000000 01110100
L'encodage little-endian prend ensuite chaque octet à droite et le met dans une chaîne d'octets:
01110100
00000000
11010010
10010111
00011011
11101101
01001001
01110100
00000000
On peut voir que, comme nous ajoutons de nouvelles parties au grand nombre à gauche (c'est-à-dire que nous ajoutons des bits significatifs), mais que nous encodons à partir de la droite (c'est-à-dire les bits les moins significatifs), l'encodage et le décodage peuvent être effectués de manière incrémentielle.
Cela se traduit finalement par
additions_four_bytes {
first_value: 489866504
rice_parameter: 30
entries_count: 2
encoded_data: "t\000\322\227\033\355It\000"
}
Le client suit simplement les étapes ci-dessus dans l'ordre inverse pour décoder les préfixes de hachage.
Décoder les indices de suppression
Les index de suppression sont encodés à l'aide de la même technique que ci-dessus, à l'aide d'entiers 32 bits.
Fréquence de mise à jour
Le client doit inspecter la valeur renvoyée par le serveur dans le champ minimum_wait_duration
et l'utiliser pour planifier la prochaine mise à jour de la base de données. Cette valeur peut être nulle (le champ minimum_wait_duration
est complètement manquant), auquel cas le client DOIT effectuer immédiatement une autre mise à jour.